0
\$\begingroup\$

Let's consider following function that return some risk levels enum type:

func calculateRiskLevel()-> ResultFirstLevels
{
    let result = self.result
    if result < 1
        {
            return .Level1
        }
    else if result >= 1 && result < 5
        {
            return .Level2
        }
    else if result >= 5 && result < 10 
        {

            return .Level3
        }
    else
        {
            return .Level4
        }

}

I'm pretty sure there is a more clever way to achieve that.

I was thinking about a dictionary with some key-value coding, but how can I incorporate conditional statements within keys?

Could you suggest some "more professional" way to deal with such parsing with conditional statements?

\$\endgroup\$
2
\$\begingroup\$

If you need risk level to be an enum (which sounds like good idea anyway), it would be nice to tightly couple the meaning of, say, Risk.Level2 with the range of raw values it represents, such as 1..<5. In other words, the enum itself should define all the applicable ranges. Depending on your specific needs, one of the following two approaches may be along the lines of what you're looking for:

enum Risk {

    case Level1, Level2, Level3, Level4

    var range: Range<Int> {
        switch self {
        case Level1: return 0..<1
        case Level2: return 1..<5
        case Level3: return 5..<10
        case Level4: return 10..<Int.max
        }
    }

    init(_ risk: Int) {
        switch risk {
        case Level2.range: self = Level2
        case Level3.range: self = Level3
        case Level4.range: self = Level4
        default: self = Level1
        }
    }
}

Risk(5) //--> Risk.Level3

Or:

enum Risk: Int {

    case Level1 = 0
    case Level2 = 1
    case Level3 = 5
    case Level4 = 10

    var range: Range<Int> {
        switch self {
        case Level1: return Level1.rawValue..<Level2.rawValue
        case Level2: return Level2.rawValue..<Level3.rawValue
        case Level3: return Level3.rawValue..<Level4.rawValue
        case Level4: return Level4.rawValue..<Int.max
        }
    }

    init(_ risk: Int) {
        switch risk {
        case Level2.range: self = Level2
        case Level3.range: self = Level3
        case Level4.range: self = Level4
        default: self = Level1
        }
    }
}

Risk(5) //--> Risk.Level3

This would all be much nicer if we could have enum Risk: Range<Int>. Unfortunately, Range<Int> cannot be expressed as a literal, so cases could not be assigned rawValues...

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

I'd rather use the switch statement.

PoC:

Example - Classic:

if num == 0 {
    return 12
} else if num == 1 {
    return 24
} else {
    return 36
}

Example - With switch statement:

switch(num) {
case 0: return 12
case 1: return 24
case 2: fallthrough
default: return 36
}

2 case is handled by the default case, using the fallthrough keyword. Now you are able to apply this method to your code.

Following the example, an alternative way to achieving the same, taking into account that the possible values are consecutive and starting from 0, is using an array:

let val = [12, 24, 36]
return val[num]

If the function is a class/struct method, the val array can be defined as a static (class) property outside the function, just to avoid instantiating it for each function call. Note that this solution generates a runtime exception if the num value is not in the [0, 2] range.

I suggest you to apply the method by using the switch statement.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ well, how to apply ranges instead of values to switch statement? how to make this if result >= 5 && result < 10 a case? \$\endgroup\$ – DCDC Nov 20 '15 at 22:55
  • \$\begingroup\$ @DCDC something like case 0..<10: which means, in this case, "between 0 and 10" \$\endgroup\$ – DrProgrammer Nov 20 '15 at 23:07
  • \$\begingroup\$ alright :) So switch would be certainly better option here :) any ideas with dictionaries? \$\endgroup\$ – DCDC Nov 20 '15 at 23:10
  • \$\begingroup\$ @DCDC To have the same code executed for two case, you could do case "first", "second": or use fallthrough keyword. \$\endgroup\$ – DrProgrammer Nov 20 '15 at 23:13
  • \$\begingroup\$ Why would you use dictionaries? \$\endgroup\$ – DrProgrammer Nov 20 '15 at 23:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.