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 theEquatable
protocol, compare e.g. Andrews's answer. - If the sequence elements are instances of a
NSObject
subclass
then you have to overrideisEqual:
, 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
How to Capture Depth Data from Camera in iOS 11 and Swift 4
Drag Rotate a Node Around a Fixed Point
Adding Local Dependencies in Xcode11 Using Spm
Sprite Kit Physicsbody.Resting Behavior
Initialize Lazy Instance Variable with Value That Depends on Other Instance Variables
Storing/Passing Function Types from Swift Protocols
How to Make Keyboard Dismiss When I Press Out of Searchbar on Swift
Swift Function with Args... Pass to Another Function with Args
How to Set Top Left and Right Corner Radius with Desired Drop Shadow in Uitabbar
Warning: Initialization of 'Unsafebufferpointer<T>' Results in a Dangling Buffer Pointer
Checking If Textfields Are Empty Swift
Difference Between String Interpolation and String Initializer in Swift
Create Nsmanagedobject Subclass... Make a New Error in My Project
Parse.Com Querying User Class (Swift)
How to Rewrite Swift ++ Operator in : Ternary Operator
How to Retrieve a Random Object from Firebase Using a Sequential Id