0

I have 2000 contacts and i want to find duplicates and the filter is taking like 1min to find duplicates.

let duplicateArray = contacts.filter { value in 
    contacts.filter({ 
        $0.phoneNumbers.first?.value.value(forKey: "stringValue") as? 
        String ?? "" == value.phoneNumbers.first?.value.value(forKey: 
        "stringValue") as? String ?? "" 
    }).count > 1  
}
えるまる
  • 2,409
  • 3
  • 24
  • 44

4 Answers4

2

Let's consider this array

let array = [1,2,3,4,3,2]

Using a dictionary, let's count how many times each element appears in the array:

var dict : [Int: Int] = [:]

for element in array {
    dict[element, default: 0] += 1
}

Now let's construct a new array that contains the elements that appear more than once in the original array:

var output = dict.flatMap { (key, value) in
    return Array(repeating: key, count: value == 1 ? 0 : value)
}

print(output)  //[3, 3, 2, 2]
ielyamani
  • 17,807
  • 10
  • 55
  • 90
1

A good way to remove duplicates is using the Set(), since a Set can only contain one of each element

let duplicates = [1, 2, 3, 3]
let unique = Set(duplicates) // will only contain 1, 2 and 3
PGDev
  • 23,751
  • 6
  • 34
  • 88
magnuskahr
  • 1,137
  • 9
  • 17
0

You can use something like this

extension Array where Element: Hashable {
   func removingDuplicates() -> [Element] {
       var addedDict = [Element: Bool]()

       return filter {
           addedDict.updateValue(true, forKey: $0) == nil
       }
   }

   mutating func removeDuplicates() {
       self = self.removingDuplicates()
   }
}
Andre Liberty
  • 707
  • 1
  • 9
  • 17
0

Since you only want the duplicated, use a combination of Dictionary's init(grouping:by:), filter(_:) and flatMap(_:).

Example:

let arr = [1, 1, 3, 1, 2, 2, 4]
let result = Dictionary(grouping: arr, by: { $0 }).filter({ $0.1.count > 1 }).flatMap({ $0.value })

print(result) //[2, 2, 1, 1, 1]
PGDev
  • 23,751
  • 6
  • 34
  • 88