Reputation: 72975
I know in Swift I can do a simple Swift switch statement to compare computed values with a single variable:
let distanceTravelled = -145.1
switch distanceTravelled {
case _ where distanceTravelled < 15:
print("You travelled the right distance")
default:
print("Sad face")
}
But I want to be able to set up a matrix of comparisons using tuples, something like this:
let distanceTravelled = -145.1,
origin = 2
switch (origin, distanceTravelled) {
case (2, _ where distanceTravelled < 15):
print("You travelled the right distance")
default:
print("Sad face")
}
But this doesn't compile, complaining that expected ',' separator
and expected expression in list of expressions
.
Obviously this is syntactically incorrect, but shouldn't it work given that this works?
switch (2, -145.1) {
case (2, _):
print("You travelled the right distance")
default:
print("Sad face")
}
Upvotes: 1
Views: 2865
Reputation: 72975
Aha! Found the answer in the good ol' Swift docs. I wasn't thinking of this in terms of the condition being a tuple.
switch (origin, distanceTravelled) {
case let (_, d) where d < 15:
print("You travelled the right distance")
default:
print("Sad face")
}
For my actual use case, this got a little weirder because I was comparing an enum
property for origin, but it worked out:
let absOriginDistanceFromDefault = abs(defaultDividerPosition - viewDividerOrigin)
switch (splitViewOrigin, distanceTravelled) {
case let (.defaultPosition, d) where d < -100:
return .shouldMoveToTopView
case let (.defaultPosition, d) where d > 100:
return .shouldMoveToBottomView
case (.topView, _) where currentDividerPosition - defaultDividerPosition < -100:
return .shouldMoveToBottomView
case (.topView, _) where abs(distanceTravelled) > absOriginDistanceFromDefault * 0.5 && currentDividerPosition < self.view.bounds.height:
return .shouldMoveToDefaultPosition
case (.bottomView, _) where currentDividerPosition - defaultDividerPosition > 100:
return .shouldMoveToTopView
case (.bottomView, _) where abs(distanceTravelled) > absOriginDistanceFromDefault * 0.3 && currentDividerPosition > 0:
return .shouldMoveToDefaultPosition
default:
return .shouldReturnToOrigin
}
And oddly enough, in simplifying it further, it turns out I don't even need to declare variables in the first two checks at all:
let absOriginDistanceFromDefault = abs(defaultDividerPosition - viewDividerOrigin)
switch (splitViewOrigin, distanceTravelled) {
case (.defaultPosition, _) where distanceTravelled < -100,
(.bottomView, _) where currentDividerPosition - defaultDividerPosition > 100:
return .shouldMoveToTopView
case (.defaultPosition, _) where distanceTravelled > 100,
(.topView, _) where currentDividerPosition - defaultDividerPosition < -100:
return .shouldMoveToBottomView
case (.topView, _) where abs(distanceTravelled) > absOriginDistanceFromDefault * 0.5 && currentDividerPosition < maxHeight,
(.bottomView, _) where abs(distanceTravelled) > absOriginDistanceFromDefault * 0.3 && currentDividerPosition > 0:
return .shouldMoveToDefaultPosition
default:
return .shouldReturnToOrigin
}
Upvotes: 5