Reputation: 555
Let's say that you have the code
if stringValue == "ab" || stringValue == "bc" || stringValue == "cd" {
// do something
}
Is there a way to shorten this condition or beautify it (preferably without using the switch statement)? I know that this code does NOT work:
if stringValue == ("ab" || "bc" || "cd") {
// do something
}
I've seen some complex solutions on other languages, but they seem language specific and not applicable to Swift. Any solutions would be appreciated.
Upvotes: 50
Views: 23782
Reputation: 2165
Not that I am aware; you can do something like this though:
let validStrings = Set(["ab", "bc", "cd"])
if validStrings.contains(str) {
//do something
}
Upvotes: 8
Reputation: 6388
You can create an extension like this:
extension Equatable {
func oneOf(_ other: Self...) -> Bool {
return other.contains(self)
}
}
and use it like this:
if stringValue.oneOf("ab", "bc", "cd") { ... }
Credit for the impl which saved me typing it: https://gist.github.com/daehn/73b6a08b062c81d8c74467c131f78b55/
Upvotes: 21
Reputation: 32814
Just for fun, how about overloading functions over String
:
if a.isOneOf("ab", "bc", "cd") {
print("yes")
}
extension String {
@inlinable
func isOneOf(_ first: String, _ second: String) -> Bool {
self == first || self == second
}
@inlinable
func isOneOf(_ first: String, _ second: String, _ third: String) -> Bool {
self == first || isOneOf(second, third)
}
@inlinable
func isOneOf(_ first: String, _ second: String, _ third: String, _ fourth: String) -> Bool {
self == first || isOneOf(second, third, fourth)
}
}
This gives you full performance benefits, as the compiler will be able to inline and tail call as much as it wants, at the cost of having to write as many overloads as you need in your code, and also not being able to pass arrays - but other answers deal with this too.
Upvotes: 1
Reputation: 34983
The construction ["some", "array"].contains("value")
works, but is somewhat annoying:
You can instead use Set(["value"]).isSubset(of: ["some", "array"])
.
The benefit is especially apparent when working with enums:
enum SomeReallyReallyLongTypeName {
case one, two
}
struct Thing {
let value: SomeReallyReallyLongTypeName
}
let thing = Thing(value: .one)
if Set([thing.value]).isSubset(of: [.one, .two]){
// :)
// Left-to-right order
// You get nice type inference
}
if [SomeReallyReallyLongTypeName.one, .two].contains(thing.value) {
// :(
// Annoying to have "SomeReallyReallyLongTypeName" in the code
}
Upvotes: 3
Reputation: 662
Use a Switch Statement.
switch stringValue {
case "ab", "bc", "cd":
print("Yay!")
default:
break
}
Upvotes: 7
Reputation: 549
if someArray.contains(object) {
// contains
} else {
// does not contains
}
The above function returns bool value, then you write logic accordingly.
Upvotes: 1
Reputation: 547
let a = 1
let b = 1
let c = 1
let d = 1
if a == b,a==c,a==d {
print("all of them are equal")
}
else {
print("not equal")
}
Upvotes: -10
Reputation: 6704
let valuesArray = ["ab","bc","cd"]
valuesArray.contains(str) // -> Bool
Upvotes: 48