iosarraysswiftnsarray

Swift search Array/NSArray for multiple values


Two faceted question:

var array = [1,2,3,4,5]
contains(array, 0) // false

var array2: NSArray = [1,2,3,4,5]
array2.containsObject(4) // true

Is there any way to search an Array for more than 1 value? ie. Can I write below to search the array for multiple values and return true if any of the values are found? Second part to the question is how can I do that for an NSArray as well?

var array = [1,2,3,4,5]
contains(array, (0,2,3)) // this doesn't work of course but you get the point

Solution

  • One option would be to use a Set for the search terms:

    var array = [1,2,3,4,5]
    let searchTerms: Set = [0,2,3]
    !searchTerms.isDisjointWith(array)
    

    (You have to negate the value of isDisjointWith, as it returns false when at least one of the terms is found.)

    Note that you could also extend Array to add a shorthand for this:

    extension Array where Element: Hashable {
        func containsAny(searchTerms: Set<Element>) -> Bool {
            return !searchTerms.isDisjointWith(self)
        }
    }
    array.containsAny([0,2,3])
    

    As for the NSArray, you can use the version of contains which takes a block to determine the match:

    var array2: NSArray = [1,2,3,4,5]
    array2.contains { searchTerms.contains(($0 as! NSNumber).integerValue) }
    

    Explanation of closure syntax (as requested in comments): you can put the closure outside the () of method call if it's the last parameter, and if it's the only parameter you can omit the () altogether. $0 is the default name of the first argument to the closure ($1 would be the second, etc). And return may be omitted if the closure is only one expression. The long equivalent:

    array2.contains({ (num) in
        return searchTerms.contains((num as! NSNumber).integerValue)
    })