Shorthand to test if an object exists in an array for Swift?
Currently, I have an array of objects like this:
var myArr = [
MyObject(name: "Abc", description: "Lorem ipsum 1."),
MyObject(name: "Def", description: "Lorem ipsum 2."),
MyObject(name: "Xyz", description: "Lorem ipsum 3.")
]
I am testing if an object exists before proceeding like this:
let item = myArr.filter { $0.name == "Def" }.first
if item != nil {
// Do something...
}
But I'm looking for a shorter way to do this since I am doing this a lot. I'd like to do something like this but it is invalid:
if myArr.contains { $0.name == "Def" } {
// Do something...
}
Is there any shorthand syntax I'm missing or a better way to do this?
Why not use the built-in contains()
function? It comes in two flavors
func contains<S : SequenceType, L : BooleanType>(seq: S, predicate: @noescape (S.Generator.Element) -> L) -> Bool
func contains<S : SequenceType where S.Generator.Element : Equatable>(seq: S, x: S.Generator.Element) -> Bool
and the first one takes a predicate as argument.
if contains(myArr, { $0.name == "Def" }) {
println("yes")
}
Update: As of Swift 2, both global contains()
functions have
been replaced by protocol extension methods:
extension SequenceType where Generator.Element : Equatable {
func contains(element: Self.Generator.Element) -> Bool
}
extension SequenceType {
func contains(@noescape predicate: (Self.Generator.Element) -> Bool) -> Bool
}
and the first (predicate-based) one is used as:
if myArr.contains( { $0.name == "Def" }) {
print("yes")
}
Swift 3:
if myArr.contains(where: { $0.name == "Def" }) {
print("yes")
}
IMHO to achieve the desired behavior you would have to create an extension class to the array that would look something like:
extension Array {
func contains(test: (T) -> Bool, action: (T) -> Void) {
let filtered = self.filter(test)
if(filtered.isEmpty) {
action(filtered)
}
}
}
I don't have xcode in front of me so I apologize if i have a syntax error. However if you are using the often you can write it as follows
myArr.contains({ $0.name == "Def"}) {
// Do something...
}
I would rename it as to prevent confusion in your code.