Using Enum in if-else in Swift - swift

I have the following for loops with if-else condition. However, it is not quite intituitve for others to read the code at a first glance. therefore I am thinking to use Enum here.
for row in 0..<result.count {
for column in 0..<result[row].count {
if column == 0 {
// add hotels here
} else if column == 1 {
// add motels here
}
}
}
I am trying to use the following enum, but I am confused how to put into if-else condition.
enum ResortColumn {
case hotel
case motel
}

If you want to compare your enum type to an integer, you need to declare it an Int and compare its rawValue.
enum ResortColumn: Int {
case hotel
case motel
}
if column == ResultColumn.hotel.rawValue { // etc.
See the second "enum Planet" example on this page, and read the rest for a full understanding of Swift enums:
https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html

enum ResortColumn: Int {
case hotel
case motel
}
for row in 0 ..< result.count {
for column in 0 ..< result[row].count {
let resortColumn = ResortColumn(rawValue: column)
switch resortColumn {
case .hotel:
// add hotels here
case .motel:
// add motels here
}
}
}
This is the best what I can come up with the context you gave. In this case, it does really matter what is behind the result variable

Related

Is there any way to create Map with enum as key that ensure operator[] is not null?

enum SomeEnum { first, second }
Map<SomeEnum, String(or any type)> someMap = {
SomeEnum.first: 'first',
SomeEnum.second: 'second',
};
String variable = someMap[SomeEnum.first]; <- nullable
In codes above, someMap[SomeEnum.{anything}] defenitely can't be null because it have all possible SomeEnum as key.
But this causing error because someMap[SomeEnum.first] is nullable, can't assign to type String
How do I tell flutter that this have all possible enum values and 100% can't be null without using ! (I don't want to use it because I use this map a lot and this is a little bit annoying)
If that is your literal enum and map you don't need that map. Use SomeEnum.first.name to get the string.
If the strings are different. I would use a different approach. When using Dart 2.17.0 or higher you can use enhanced enums and simple add methods to enums like this for example
enum SomeEnum { first, second;
String getString() {
switch (this) {
case SomeEnum.first: return "first string";
case SomeEnum.second: return "second string";
}
}
int toInt() {
switch (this) {
case SomeEnum.first: return 1;
case SomeEnum.second: return 2;
}
}
}
And then use Some.first.getString() wherever you need. Or Some.first.toInt() to get ints
For lower Dart versions you can write an extension instead and use it in the same way:
extension SomeEnumExtension on SomeEnum {
String getString() {
switch (this) {
case SomeEnum.first: return "first string";
case SomeEnum.second: return "second string";
}
}
}

How to assign raw value to enum in Dart?

In Swift, you can easily assign raw value to enum, eg:
enum Game: Int {
case lol = 1
case dnf = 2
case dota = 3
}
However, you can't assign raw value to enum in Dart:
enum Game {
lol = 1,
dnf = 2,
dota = 3,
}
It's showed error and you can only use the simplest enum:
enum Game {
lol,
dnf,
dota,
}
It's really let me down.
Any way assign raw value to Dart's enum like Swift?
Dart 2.17 support enhanced enum
enum Game {
lol(1),
dnf(2),
dota(3);
const Game(this.value);
final int value;
}
Use it like:
void main() {
const game = Game.lol;
print(game.value); // 1
}
There's an upcoming feature in Dart known as enhanced enums, and it allows for enum declarations with many of the features known from classes. For example:
enum Game {
lol,
dnf,
dota;
int get intValue => index + 1;
}
The feature is not yet released (and note that several things are not yet working), but experiments with it can be performed with a suitably fresh version of the tools by passing --enable-experiment=enhanced-enums.
The outcome is that an enum value of type Game will have a getter intValue that returns the int values mentioned in the question, so print(myGame.intValue) will print 1, 2, or 3.
You can use enum extensions for example
enum EnumAction { subtract, add }
extension EnumActionExtension on EnumAction {
String get name {
switch (this) {
case EnumAction.add:
return 'add';
case EnumAction.subtract:
return 'subtract';
}
}
}
In your case you would return an int and an int value. Enums also have int values assigned to them by default, their respective index. You could call Game.lol.index and it would return 0.
To get an int value, simply pass an enum to the enumGame function.
enum EnumGame { lol, dnf, dota }
enumGame(EnumGame enumGame) {
switch (enumGame) {
case EnumGame.lol:
return 1;
case EnumGame.dnf:
return 2;
case EnumGame.dota:
return 3;
default:
return -1;
}
}

Enum Associated Value Lookup

I have an enum with different associated value custom classes. Then trying to create a calculated value to determine if one particular type and return the value if so. The below works using a switch in the calculated value but seems a bit clumsy. Are there any cleaner approaches? Thanks.
private enum Situation: Equatable {
case inLocation(LocationMO)
case heldByBeing(BeingMO)
case inContainer(PhysicalObjectMO)
}
private var isInSituation: Situation
var isInLocation: LocationMO? {
switch isInSituation {
case .inLocation(let validLocation): return validLocation
default: return nil
}
}

How to do if pattern matching with multiple cases?

I'm searching for the syntax to do pattern matching with multiple cases in an if case statement.
The example would be this:
enum Gender {
case Male, Female, Transgender
}
let a = Gender.Male
Now I want to check, if a is .Male OR .Female. But I would like to avoid using switch for this. However the switch statement would be like this:
switch a {
case .Male, .Female:
// do something
}
Is it possible to write this with if case?
I would expect this, but it didn't work :(
if case .Male, .Female = a {
}
A simple array does the trick:
if [.Male, .Female].contains(a) {
print("Male or female")
} else {
print("Transgender")
}
I'm simply amazed at Swift's ability to infer type. Here, it gets that .Male and .Female are of type gender from a.
If you have an associated value, you can simply create a Bool variable like this
extension Gender {
var isMaleOrFemale: Bool {
switch self {
case .Male, .Female:
return true
default:
return false
}
}
And usage:
if a.isMaleOrFemale {
// Your code here
}
You should use a collection. In JavaScript I would write something like this:
if ([Gender.Male, Gender.Female].includes(actualGender))
console.log(actualGender);
Note that I have not a clue about swift, or how to do the same in that language, so here is a relevant answer in the topic: https://stackoverflow.com/a/25391725/607033 :D
EDIT: This is the Swift version:
if [.Male, .Female].contains(a) {
}
For pattern matching, what you describe will not work yet. You could do this in your case. But if it cannot be convert into a hashValue. Then this would not work either.
// Using Pattern Matching for more than one case.
if case 0...2 = a.hashValue {
print("Hello")
}
//Normal if else
if a == .Male || a == .Female {
print("Hello")
}

Nested and Associated Enum Values Swift

One of the best practices endorsed by NSHipster when dealing with tables or collection views is to use an enum to represent each section like so:
typedef NS_ENUM(NSInteger, SomeSectionType) {
SomeSectionTypeOne = 0,
SomeSectionTypeTwo = 1,
SomeSectionTypeThree = 2
}
That makes it really easy to do a switch statement or ifs like:
if(indexPath.section == SomeSectionTypeOne) {
//do something cool
}
For sections with static content, I extended the concept to include enums for each item:
typedef NS_ENUM(NSInteger, SectionOneItemType) {
ItemTypeOne = 0,
ItemTypeTwo = 1
}
if(indexPath.section == SomeSectionTypeOne) {
switch(indexPath.item) {
case SectionOneItemType:
//do something equally cool
default:
}
}
In Swift, I'd like to replicate the same behavior except this time taking advantage of nested enums. I've been able to come up with this so far:
enum PageNumber {
enum PageOne: Int {
case Help, About, Payment
}
enum PageTwo: Int {
case Age, Status, Job
}
enum PageThree: Int {
case Information
}
case One(PageOne)
case Two(PageTwo)
case Three(PageThree)
}
but I can't see how to go from an NSIndexPath and initialize the correct case and then use a switch statement to extract the values.
Don't think you can use nested enum to decide the section and row cell comes from. Because associated values and raw values can't coexist in Swift enumeration. Multiple enums are needed
enum sectionType: Int {
case sectionTypeOne = 0, sectionTypeTwo, sectionTypeThree
}
enum rowTypeInSectionOne: Int {
case rowTypeOne = 0, rowTypeTwo, rowTypeThree
}
//enum rowTypeInSectionTwo and so on
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
switch (indexPath.section, indexPath.row) {
case (sectionType.sectionTypeOne.rawValue, rowTypeInSectionOne.rowTypeOne.rawValue):
print("good")
default:
print("default")
}