Multiple enum types list all cases
Here is a demo of possible solution. Prepared with Xcode 12.1 / iOS 14.1
enum Fish: String, CaseIterable {
case goldfish
case blueTang = "blue_tang"
case shark
}
func view<T: CaseIterable & Hashable>(for type: T.Type) -> some View where T.AllCases: RandomAccessCollection {
VStack(alignment: .leading) {
Text(String(describing: type)).bold()
ForEach(type.allCases, id: \.self) { item in
Text(String(describing: item))
}
}
}
struct FishDemoView: View {
var body: some View {
view(for: Fish.self)
}
}
Is it possible group & represent multiple cases as another case within an enum in Swift?
You can used nested Enum and a case with parameter
enum Devices {
case phone(iPhone)
case tablet(iPad)
enum iPhone {
case phone7
case phoneX
}
enum iPad {
case mini
case pro
}
}
let randomDevice = Devices.phone(.phone7)
switch randomDevice {
case .phone:
print("Its a phone")
default:
break
}
// prints "Its a phone"
How do you pass multiple enum values in C#?
When you define the enum, just attribute it with [Flags], set values to powers of two, and it will work this way.
Nothing else changes, other than passing multiple values into a function.
For example:
[Flags]
enum DaysOfWeek
{
Sunday = 1,
Monday = 2,
Tuesday = 4,
Wednesday = 8,
Thursday = 16,
Friday = 32,
Saturday = 64
}
public void RunOnDays(DaysOfWeek days)
{
bool isTuesdaySet = (days & DaysOfWeek.Tuesday) == DaysOfWeek.Tuesday;
if (isTuesdaySet)
//...
// Do your work here..
}
public void CallMethodWithTuesdayAndThursday()
{
this.RunOnDays(DaysOfWeek.Tuesday | DaysOfWeek.Thursday);
}
For more details, see MSDN's documentation on Enumeration Types.
Edit in response to additions to question.
You won't be able to use that enum as is, unless you wanted to do something like pass it as an array/collection/params array. That would let you pass multiple values. The flags syntax requires the Enum to be specified as flags (or to bastardize the language in a way that's its not designed).
Multiple Enums with same case
You could create one state enum that uses generics:
enum ViewModelState<T> {
case failure(String)
case anotherState(T)
}
Check enum for multiple values
I ended up writing a method:
public static enum FileType {
CSV, XML, XLS, TXT, FIXED_LENGTH;
// Java < 8
public boolean in(FileType... fileTypes) {
for(FileType fileType : fileTypes) {
if(this == fileType) {
return true;
}
}
return false;
}
// Java 8
public boolean in(FileType... fileTypes) {
return Arrays.stream(fileTypes).anyMatch(fileType -> fileType == this);
}
}
And then:
if(fileType.in(FileType.CSV, FileType.TXT, FileType.FIXED_LENGTH)) {}
Nice and clean!
How could I use the multiple Enum raw values of type Int in Swift?
Enum
cases can not have multiple rawValues. Becase imagine you call this:
print( STATUS_CODE.onGoing.rawValue )
What value you expect to be printed?
Instead you can have a custom enum like the one you think of:
enum STATUS_CODE: RawRepresentable {
init(rawValue: Int) {
switch rawValue {
case 5, 50,70, 90: self = .onGoing(rawValue)
case 10: self = .atWorkshop
case 16: self = .completed
case 35: self = .comedy
case 80: self = .crime
case 0: self = .NoDate
default: self = .unknown(rawValue)
}
}
var rawValue: Int {
switch self {
case .onGoing(let rawValue): return rawValue
case .atWorkshop: return 10
case .completed: return 16
case .comedy: return 35
case .crime: return 80
case .NoDate: return 0
case .unknown(let rawValue): return rawValue
}
}
case onGoing(Int)
case atWorkshop
case completed
case comedy
case crime
case NoDate
case unknown(Int)
func getString() -> String {
switch self {
case .onGoing : return "New order"
case .atWorkshop: return "At workshop"
case .completed : return "Animation"
case .comedy : return "Comedy"
case .crime : return "Crime"
case .NoDate : return "No Order"
case .unknown(let rawValue): return "Unknown \(rawValue)"
}
}
}
ofcourse it is a demo and can be refactored ;)
Create a DRY function for multiple enums (enum subclassing?)
A protocol is the right approach. Not sure why do you think protocols cannot inherit from each other, but they can, so you can make your protocol inherit from CaseIterable
.
You can also significantly simplify titled
by using map
instead of a for..in
loop and getting rid of the useless get
specifier. A getter is the default accessor for a computed property, you don't need to wrap your closure in get { ... }
unless you are creating both a getter and a setter.
protocol Titled: CaseIterable {
var title: String { get }
static var titles: [String] { get }
}
extension Titled {
static var titles: [String] { allCases.map(\.title) }
}
Then you just need to keep the title
property on your enums and make them conform to Titled
and due to the default implementation you get titles
for free.
Unrelated to your question, but enum cases should be lowerCamelCase like all variables.
enum CustomerTypes: Int, Titled {
case newCustomer = 0
case existingCustomer
case myself
var title: String {
switch self {
case .newCustomer : return "new"
case .existingCustomer : return "existing"
case .myself : return "my"
}
}
}
enum EnquiryTypes: Int, Titled {
case phone = 0
case faceToFace
var title: String {
switch self {
case .phone : return "phone"
case .faceToFace : return "face"
}
}
}
How to get all enum values as an array
For Swift 4.2 (Xcode 10) and later
There's a CaseIterable
protocol:
enum EstimateItemStatus: String, CaseIterable {
case pending = "Pending"
case onHold = "OnHold"
case done = "Done"
init?(id : Int) {
switch id {
case 1: self = .pending
case 2: self = .onHold
case 3: self = .done
default: return nil
}
}
}
for value in EstimateItemStatus.allCases {
print(value)
}
For Swift < 4.2
No, you can't query an enum
for what values it contains. See this article. You have to define an array that list all the values you have. Also check out Frank Valbuena's solution in "How to get all enum values as an array".
enum EstimateItemStatus: String {
case Pending = "Pending"
case OnHold = "OnHold"
case Done = "Done"
static let allValues = [Pending, OnHold, Done]
init?(id : Int) {
switch id {
case 1:
self = .Pending
case 2:
self = .OnHold
case 3:
self = .Done
default:
return nil
}
}
}
for value in EstimateItemStatus.allValues {
print(value)
}
Java enum with multiple value types
First, the enum methods shouldn't be in all caps. They are methods just like other methods, with the same naming convention.
Second, what you are doing is not the best possible way to set up your enum. Instead of using an array of values for the values, you should use separate variables for each value. You can then implement the constructor like you would any other class.
Here's how you should do it with all the suggestions above:
public enum States {
...
MASSACHUSETTS("Massachusetts", "MA", true),
MICHIGAN ("Michigan", "MI", false),
...; // all 50 of those
private final String full;
private final String abbr;
private final boolean originalColony;
private States(String full, String abbr, boolean originalColony) {
this.full = full;
this.abbr = abbr;
this.originalColony = originalColony;
}
public String getFullName() {
return full;
}
public String getAbbreviatedName() {
return abbr;
}
public boolean isOriginalColony(){
return originalColony;
}
}
Related Topics
Environmentobject VS Singleton in Swiftui
Swift: How to Get Everything After a Certain Set of Characters
Singleton and Init with Parameter
How to Change the Current Day's Hours and Minutes in Swift
Uiview Background Color in Swift
Repeating Animation on Swiftui Image
How to Shuffle an Array So That No Two Consecutive Values Are the Same
How to Make Uitextfield Behave Like a Uisearchbar in Swift
Codable Class Does Not Conform to Protocol Decodable
Appearance Proxies/Ui_Appearance_Selector in Swift
Add a Border with Cornerradius to an Image in Swiftui Xcode Beta 5
How to Destroy a Singleton in Swift
How to Reset Intent Extension Configurations in Widgetkit
How to Compare Just the Time of a Date in Swift
Macos Command Line Tool with Swift Cocoa Framework: Library Not Loaded