I am working removing the duplicate Dictionaries in an array of Dictionaries in swift 3.0
The below is the
let Dict1 : [String : String] = ["messageTo":"Madhu"]
let Dict2 : [String : String] = ["messageTo":"Kiran"]
let Dict3 : [String : String] = ["messageTo":"Raju"]
var arrOfDict = [[String:String]]()
arrOfDict.append(Dict1)
arrOfDict.append(Dict2)
arrOfDict.append(Dict1)
arrOfDict.append(Dict3)
arrOfDict.append(Dict2
print(arrOfDict)
//prints [["messageTo": "Madhu"], ["messageTo": "Kiran"], ["messageTo": "Madhu"], ["messageTo": "Raju"], ["messageTo": "Kiran"]]
As you can see there are 2 duplicate dictionaries in the arrOfDict.
can any one help me out in filtering the duplicates using Set or any other approach
Dictionaries does not conform to Hashable
(or Equatable
), so using Set
is not an available approach in this case. For dictionaries where Key
and Value
types are Equatable
, however, we have access to the ==
operator for readily performing a uniqueness filtering of the array of dictionaries:
public func ==<Key : Equatable, Value : Equatable>(
lhs: [Key : Value], rhs: [Key : Value]) -> Bool
E.g. as follows (O(n^2)
)
arrOfDict = arrOfDict.enumerated()
.filter { (idx, dict) in !arrOfDict[0..<idx].contains(where: {$0 == dict}) }
.map { $1 }
print(arrOfDict)
// [["messageTo": "Madhu"], ["messageTo": "Kiran"], ["messageTo": "Raju"]]
// or ...
arrOfDict = arrOfDict.enumerated()
.flatMap { (idx, dict) in !arrOfDict[0..<idx].contains(where: {$0 == dict}) ? dict : nil }
func removeDuplicates(_ arrayOfDicts: [[String: String]]) -> [[String: String]] {
var removeDuplicates = [[String: String]]()
var arrOfDict = [String]()
for dict in arrayOfDicts {
if let name = dict["messageTo"], ! arrOfDict.contains(name) {
removeDuplicates.append(dict)
arrOfDict.append(name)
}
}
return removeDuplicates
}
The reason why it is duplicated, because you add Dict1
and Dict2
2 times. May i ask why?
Set
would not work for you, because Dictionary
type does not conform to the Hashable
protocol, only its key
property.
You can do a validation on the dictionary, if there is already a value like that, do not append it to arrOfDict
.
you can try this :
var set = NSSet(array: arrOfDict)