Swift Arrays and Contains, How to Determine If a Collection Contains an Object or Value

Swift arrays and contains, how to determine if a collection contains an object or value?

Swift 1:

let array = ["1", "2", "3"]
let contained = contains(array, "2")
println(contained ? "yes" : "no")

Swift 2, 3, 4:

let array = ["1", "2", "3"]
let contained = array.contains("2")
print(contained ? "yes" : "no")

Swift: Determine if a array of custom objects contains a particular string

Add something like this

func contains(make: String) -> Bool {
carArray.compactMap(\.make).contains(make)
} // returns true in your case for "BMW"

This has two parts. First, I am mapping the array of Car objects to an array of String? by mapping over the make key path. Since this may have nil values, I am using compactMap to remove the nil values.

If you are going to be doing this a lot and don't want the overhead of mapping and checking every time then create something to store your cars. Something like this:

struct Car {
var make: String?
var model: String?
var year: Double?
}

struct CarStore {
private(set) var storage: [Car] = .init()
private var makes: Set<String> = .init()

mutating func add(car: Car) {
storage.append(car)
car.make.map { makes.insert($0) } // map to run the closure only if make is not nil
}

func contains(make: String) -> Bool {
makes.contains(make)
}
}

var store = CarStore()

store.add(car: Car(make: "Audi", model: "S5", year: 2015))
store.add(car: Car(make: "BMW", model: "X3", year: 2016))
store.add(car: Car(make: "Honda", model: "Accord", year: 2018))

store.contains(make: "BMW") // -> true

Swift - Check if array contains element with property

Yes,

if things.contains(where: { $0.someProperty == "nameToMatch" }) {
// found
} else {
// not
}

How to check if an element is in an array

Swift 2, 3, 4, 5:

let elements = [1, 2, 3, 4, 5]
if elements.contains(5) {
print("yes")
}

contains() is a protocol extension method of SequenceType (for sequences of Equatable elements) and not a global method as in
earlier releases.

Remarks:

  • This contains() method requires that the sequence elements
    adopt the Equatable protocol, compare e.g. Andrews's answer.
  • If the sequence elements are instances of a NSObject subclass
    then you have to override isEqual:, see NSObject subclass in Swift: hash vs hashValue, isEqual vs ==.
  • There is another – more general – contains() method which does not require the elements to be equatable and takes a predicate as an
    argument, see e.g. Shorthand to test if an object exists in an array for Swift?.

Swift older versions:

let elements = [1,2,3,4,5]
if contains(elements, 5) {
println("yes")
}

Check item contains in model object array in swift 3

Here you go.

let contains = UsersCollection.contains{ $0.id == 0 }

Edit:

let object = UsersCollection.first{ $0.id == 0 } // object is optional here.

Swift - Determine if Array1 contains at least one object from Array2

You can do this by simply passing in your array2's contains function into your array1's contains function (or vice versa), as your elements are Equatable.

let array1 = [2, 3, 4, 5]
let array2 = [20, 15, 2, 7]

// this is just shorthand for array1.contains(where: { array2.contains($0) })
if array1.contains(where: array2.contains) {
print("Array 1 and array 2 share at least one common element")
} else {
print("Array 1 doesn't contains any elements from array 2")
}

This works by looping through array 1's elements. For each element, it will then loop through array 2 to check if it exists in that array. If it finds that element, it will break and return true – else false.

This works because there are actually two flavours of contains. One takes a closure in order to check each element against a custom predicate, and the other just compares an element directly. In this example, array1 is using the closure version, and array2 is using the element version. And that is the reason you can pass a contains function into another contains function.


Although, as correctly pointed out by @AMomchilov, the above algorithm is O(n2). A good set intersection algorithm is O(n), as element lookup is O(1). Therefore if your code is performance critical, you should definitely use sets to do this (if your elements are Hashable), as shown by @simpleBob.

Although if you want to take advantage of the early exit that contains gives you, you'll want to do something like this:

extension Sequence where Iterator.Element : Hashable {

func intersects<S : Sequence>(with sequence: S) -> Bool
where S.Iterator.Element == Iterator.Element
{
let sequenceSet = Set(sequence)
return self.contains(where: sequenceSet.contains)
}
}

if array1.intersects(with: array2) {
print("Array 1 and array 2 share at least one common element")
} else {
print("Array 1 doesn't contains any elements from array 2")
}

This works much the same as the using the array's contains method – with the significant difference of the fact that the arraySet.contains method is now O(1). Therefore the entire method will now run at O(n) (where n is the greater length of the two sequences), with the possibility of exiting early.

How do I check if an object is a collection? (Swift)

Collection can no longer be used for type-checking, hence Ahmad F's solution would no longer compile.

I did some investigation. Some people advice to bridge to obj-c collections and use isKindOfClass, others try to employ reflection (by using Mirror). Neither is satisfactory.

There's a pretty straight-forward, a bit rough yet efficient way to accomplish the task via splitting object type if our concern is Array, Dictionary or Set (list can be updated):

func isCollection<T>(_ object: T) -> Bool {
let collectionsTypes = ["Set", "Array", "Dictionary"]
let typeString = String(describing: type(of: object))

for type in collectionsTypes {
if typeString.contains(type) { return true }
}
return false
}

Usage:

var set : Set! = Set<String>()
var dictionary : [String:String]! = ["key" : "value"]
var array = ["a", "b"]
var int = 3
isCollection(int) // false
isCollection(set) // true
isCollection(array) // true
isCollection(dictionary) // true

Hard-code is the drawback but it does the job.

Check if array contains element in Swift 4

Thanks to your comments made me check the declaration of the array and the problem was that was declared as [Any] after I get it's value from the UserDefaults. I have checked and found the solution on How do I save an Int array in Swift using NSUserDefaults?

// old declaration
let categories = userDefaults.array(forKey:"categories") ?? [Int]()

// new correct declaration
var categories = [Int]()
if let temp = userDefaults.array(forKey:"categories") as? [Int] {
categories = temp
}

How to determine if one array contains all elements of another array in Swift?

Instead of iterating through arrays and doing filtering yourself, you can use NSSet to do all the work for you.

var list:Array<Int> = [1,2,3,4,5]
var findList:Array<Int> = [1,3,5]

let listSet = NSSet(array: list)
let findListSet = NSSet(array: findList)

let allElemtsEqual = findListSet.isSubsetOfSet(otherSet: listSet)

NSSet is a lot faster than arrays at checking if it contains any object. In fact it's what it's designed for.

Edit: Using Swift's built-in Set.

let list = [1,2,3,4,5]
let findList = [1,3,5]
let listSet = Set(list)
let findListSet = Set(findList)
//**Swift 4.2 and Above**
let allElemsContained = findListSet.isSubset(of: listSet)

//below versions
//let allElemsContained = findListSet.isSubsetOf(listSet)

how to check if a property value exists in array of objects in swift

You can filter the array like this:

let results = objarray.filter { $0.id == 1 }

that will return an array of elements matching the condition specified in the closure - in the above case, it will return an array containing all elements having the id property equal to 1.

Since you need a boolean result, just do a check like:

let exists = results.isEmpty == false

exists will be true if the filtered array has at least one element



Related Topics



Leave a reply



Submit