Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shorthand to test if an object exists in an array for Swift?

Tags:

arrays

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?

like image 408
TruMan1 Avatar asked Apr 16 '15 15:04

TruMan1


People also ask

How do you check if an object is in an array Swift?

It's easy to find out whether an array contains a specific value, because Swift has a contains() method that returns true or false depending on whether that item is found. For example: let array = ["Apples", "Peaches", "Plums"] if array.

How do you check if an element belongs to an array?

The simplest and fastest way to check if an item is present in an array is by using the Array. indexOf() method. This method searches the array for the given item and returns its index. If no item is found, it returns -1.

How do you check if an array contains a string Swift?

To check if a specific string is present in a String array in Swift, call contains(_:) method on the String Array and pass the specific String as argument to the contains() method.


2 Answers

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") } 
like image 60
Martin R Avatar answered Sep 18 '22 10:09

Martin R


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.is​Empty) {             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.

like image 26
Nathan Avatar answered Sep 19 '22 10:09

Nathan