Intersect Array of object in iOS swift with efficiency and without using for loop

swift set intersection
swift find same object in two array
filter two arrays swift

I want to Intersect two arrays that contains "People" objects and array size could be more then 10000 for each array and i want to intersect using "id" of objects without using for loop. i have already used for loop my solution but speed is slow. Some People objects can have same "id" in both array and some objects can have different "id"'s.

Below is sample example of my code

Example :

class People {

    var id:Int!

    var name:String!

}

let object1 = People(10, John)

let object2 = People(5, Rocky)

let array1 = [object1, object2, .... , object10000]

let array2 = [objectA1, objectA2, .... , objectA10000]

Here is simple example

Suppose your struct is

struct User:Hashable {
    let id:Int
}

and your array

let array1 = [User(id:1),User(id:2),User(id:3),User(id:4),User(id:5)]
let array2 = [User(id:1),User(id:20),User(id:3),User(id:4),User(id:5)]

Now you can create set

let set1:Set<Int> = Set(array1.map{$0.id})
let set2:Set<Int> = Set(array2.map{$0.id})

and

let unique = set1.intersection(set2)
let elements = (array1 + array2).filter{unique.contains($0.id)}
print(elements)

Hope it is helpful

Overview. You use a set instead of an array when you need to test efficiently for For example, you can efficiently test a set for membership of an element or check its intersection with another set: Set operations are not limited to use with other sets. You can iterate through a set's unordered elements with a for - in loop. For-in Loop syntax. You can create a for in loop in Swift as: for <value> in <range> { <some work here> } The above loop iterates over a range and we can access each element returned from the range in <value> variable. If you don’t know about range, you can check the article: Swift Ranges.

You can create Set with PeopleIds and Set with Object Id, something like this:

let peoples = ...
let objects = ...

let peoplesIds = peoples.map { $0.id }
let objectsIds = objects.map { $0.id }

let peoplesIdsSet = Set(peoplesIds)
let objectsIdsSet= Set(objectsIds)

let intersectionsIds = Array(peoplesIdsSet.intersection(objectsIdsSet))

Also I advise you to put it work in background thread, something like this:

DispatchQueue.global(qos: .background).async {

    findIntersecionsIds()

    DispatchQueue.main.async {
        // done
    }
}

By using a set here rather than, for instance, an array - we can avoid any We often need to perform this kind of lookup in performance-critical code paths (like The most obvious way to implement this might be to use a for loop, like this: Finally, we can also form an intersection - a set of all common  The difference is that forEach() can’t skip over any items – you can’t exit the loop part way, without processing the rest of the items. This helps people reading your code to figure out your intent: you want to act on all items, and won’t stop in the middle.

The best way to perform an intersection is to use a Set. In order to add your items to a set, they need to be Hashable. Here is an implementation of your People class that is Hashable, and CustomStringConvertible (so that is can be printed nicely):

class People: Hashable, CustomStringConvertible {

    var id: Int
    var name: String

    var hashValue: Int { return id }
    var description: String { return "People(name: \(name), id: \(id)" }


    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }

    // In order to conform to Hashable, you also need to be Equatable
    // Here we define equality as having the same id        
    static func ==(lhs: People, rhs: People) -> Bool {
        return lhs.id == rhs.id
    }
}

let object1 = People(id: 10, name: "John")
let object2 = People(id: 5, name: "Rocky")

let array1 = [object1, object2]

let array2 = [People(id: 10, name: "John"), People(id: 7, name: "Jane")]

let intersection = Array(Set(array1).intersection(array2))
print(intersection)
[People(name: John, id: 10]

Get started with this two part guide about the different built-in Swift collection types and how to implement the most The efficiency of these data structures affects our software as a whole. No problem, we'll create a DataPair structure! Let's get a closer look at the built-in Array, Set, and Dictionary types. Complexity: Amortized O(1) unless self's storage is shared with another live array; O(count) if self does not wrap a bridged NSArray; otherwise the efficiency is unspecified. I'm looking for a cons like operator for Swift. It should return a new immutable array with the element tacked on the end, in constant time, without changing the original array. I've not yet found a standard function that does this.

Assuming you want an Array of People, which is made from array2 by take out objects those are not present in array1.

Then just 2 lines:

let idSet1 = Set(array1.lazy.map{$0.id})
let interSection = array2.filter{idSet1.contains($0.id)}

Testing code:

import Foundation

class People {
    var id: Int
    var name: String

    init(id: Int, name: String) {
        self.id = id
        self.name = name
    }
}

do {
    //Generate random testing data
    let array1: [People] = (0..<20000).filter{_ in Int.random(in: 0...1) == 0}.map{People(id: $0, name: "P($0)")}
    print(array1.count)
    let array2: [People] = (0..<20000).filter{_ in Int.random(in: 0...1) == 0}.map{People(id: $0, name: "P($0)")}
    print(array2.count)

    let start = Date()
    let idSet1 = Set(array1.lazy.map{$0.id})
    let interSection = array2.filter{idSet1.contains($0.id)}
    let end = Date()
    print(interSection.count, end.timeIntervalSince(start))
}

If you assign an array, a set, or a dictionary to a constant, that collection is immutable enables the Swift compiler to optimize the performance of the collections you create. You can iterate over the entire set of values in an array with the for - in loop: A hash value is an Int value that is the same for all objects that compare  I have two arrays . Array1 contains 15 objects and Array2 contains 4 objects. There are 2 common objects from both array, I just want to get that resulted array of that 2 objects. It should be like intersection of two Set, but how to do in Objective C for array..? Please help. thanks.

The inserted elements: Elements that are not in the first array, but are in the second array. It took me a while to figure out the algorithm, with many for loops and even a continue with a label. to 25% of the original approach, which is really close to the iterative performance. iOS Developer at Revolut. Swift makes it easy to create arrays in your code using an array literal: simply surround a comma-separated list of values with square brackets. Without any other information, Swift creates an array that includes the specified values, automatically inferring the array’s Element type.

In Swift there are three primary collection types - arrays, dictionaries and sets. Intersect / Intersect In Place; Union / Union in Place; Exclusive OR / Exclusive OR in Place This means that when we declare a set using initialiser syntax we not only to a set, all we do is use the insert(_:) function multiple times within a loop:. By default, most types in the standard library are hashable, including strings, numeric and Boolean types, enumeration cases without associated values, and even sets themselves. Swift makes it as easy to create a new set as to create a new array. Simply assign an array literal to a variable or constant with the Set type specified.

very different. Let's find out how you can use sets when building iOS apps! Just like arrays and dictionaries, Set is a generic struct . A set can In the above code, the "orange" string is not inserted in the set. This idea is revolutionary, because it means we can efficiently find any item in the collection. In order to define a custom object in swift, you'll need to define a struct data format, by defining it with the name of the new object you're creating and with the custom data structure. Moreover, you can use the init function to create a struct constructor .

Comments
  • "Intersect". What's the condition of equality?
  • @Larme id. It's there in the question.
  • Have you tried using NSSet/Set? developer.apple.com/documentation/swift/set
  • What do you mean by intersect? Intersection usually means something common between two things. Here, you seem to be talking about filtering but using the word intersection.
  • I want to take out objects those are not present in array1. I tried with NSSet/Set. but not getting solution for me
  • I am sorry if i am wrong but he needs only in ID field. He don't want any other parameter to match !!!