Swift - 多个交换机案例

时间:2017-03-28 00:35:44

标签: swift switch-statement

我正在制作一个必须加入两个物体的棋盘游戏。每个对象都有一个类型,有5种不同的类型。对于合并中的每种不同类型组合,将对游戏产生不同的影响。现在,我正在为每个组合使用switch语句。所以,我的代码看起来像这样。

struct Coin {
    var type = 1
}

// Each coin is of type Coin.   
switch(coin1.type, coin2.type) {
    case (1,1):
        functionNormal()
    case (1,2):
        functionUncommon()
    case (1,3):
        functionRare()
    ...
}

对象'位置不会改变结果。 (1,2)合并将具有与(2,1)合并相同的效果。是否有一种不那么冗长的方法来实现这一目标?

4 个答案:

答案 0 :(得分:16)

怎么样:

struct Object{
    var type = 1
}

let lowType  = min(object1.type,object2.type)
let highType = max(object1.type,object2.type)
switch( lowType, highType )
{
  case (1,1):
      doSome()
  case (1,2):
      doSome2()
  case (1,3):
    doSome3()
  ...
  // you will only need to specify the combinations where the first
  // type is less or equal to the other.
}

如果您经常这样做,您可以定义一个minMax函数,以进一步减少每次所需的代码量:

func minMax<T:Comparable>(_ a:T, _ b:T) ->(T,T) 
{ return a<b ? (a,b) : (b,a) }

switch minMax(object1.type,object2.type)
{
  case (1,1):
      doSome()
  case (1,2):
      doSome2()
  ...

请注意,您也可以将每个反转对放在case语句中:

switch(object1.type,object2.type)
{
  case (1,1):
      doSome()
  case (1,2),(2,1):
      doSome2()
  case (1,3),(3,1):
      doSome3()
  ...
}

<强> [UPDATE]

如果您在&#34;排列不敏感&#34;中有两个以上的值要比较?时尚,您可以通过创建具有更多值的变体来扩展minMax()的想法:

func minToMax<T:Comparable>(_ a:T, _ b:T) -> (T,T) 
{ return a<b ? (a,b) : (b,a) }

func minToMax<T:Comparable>(_ a:T, _ b:T, _ c:T) -> (T,T,T) 
{ return { ($0[0],$0[1],$0[2]) }([a,b,c].sorted()) }

func minToMax<T:Comparable>(_ a:T, _ b:T, _ c:T, _ d:T) -> (T,T,T,T) 
{ return { ($0[0],$0[1],$0[2],$0[3]) }([a,b,c,d].sorted()) }

switch minToMax(object1.type,object2.type,object3.type)
{
   case (1,2,3)      : doSome1() // permutations of 1,2,3
   case (1,2,4)      : doSome2() // permutations of 1,2,4
   case (1,2,_)      : doSome3() // permutations of 1,2,anything else
   case (1,5...6,10) : doSome4() // more elaborate permutations
   ...
}

}

答案 1 :(得分:10)

您可以将逗号分隔的多个案例传递给

   switch switchValue {
    case .none:
        return "none"
    case .one, .two:
        return "multiple values from case 2"
    case .three, .four, .five:
        return "Multiple values from case 3"
    }

答案 2 :(得分:2)

object1.typeobject2.type分配给两个临时变量(我称之为ab),使a始终小于b }。现在,您只需枚举第一个数小于第二个数的情况。

struct Object {
    var type = 1
}

let (a, b) = object1.type < object2.type ? (object1.type, object2.type) : (object2.type, object1.type)
switch (a, b) {
case (1, 1): print("(1, 1)")
case (1, 2): print("(1, 2)")
case (1, 3): print("(1, 3)")
case (1, 4): print("(1, 4)")
case (1, 5): print("(1, 5)")
case (2, 2): print("(2, 2)")
case (2, 3): print("(2, 3)")
case (2, 4): print("(2, 4)")
case (2, 5): print("(2, 5)")
case (3, 3): print("(3, 3)")
case (3, 4): print("(3, 4)")
case (3, 5): print("(3, 5)")
case (4, 4): print("(4, 4)")
case (4, 5): print("(4, 5)")
case (5, 5): print("(5, 5)")

default: preconditionFailure("Values must each be in the range 1...5, with the first less than the second. Found: (\(a)\(b))")
}

答案 3 :(得分:2)

您可以将对象抛出到一个集合(本质上是无序的)并检查该集合是否包含元素的组合。你有15(5!= 5 + 4 + 3 + 2 + 1)个案,所以你有15个ifs。

    enum PrimaryColor {
        case red, yellow, blue
    }
    enum SecondaryColor {
        case orange, green, purple
        init?(firstColor: PrimaryColor, secondColor: PrimaryColor) {
            let colors = Set<PrimaryColor>([firstColor, secondColor])
            if colors.contains(.red)  && colors.contains(.blue) {
                self = .purple
                return
            }
            if colors.contains(.yellow)  && colors.contains(.blue) {
                self = .green
                return
            }
            if colors.contains(.red)  && colors.contains(.yellow) {
                self = .orange
                return
            }
            //if you care about the diagonal check firstColor == secondColor  && colors.contains(.red) etc.
            return nil
        }
    }