How to quickly remove duplicates from Array & keep order
Removing duplicates (objects, characters, ..) is swift in Swift thanks to the Set type. We can also leverage NSOrderedSet to not lose order of the items.
Published: May 22, 2020 Sponsored See booksThe problem
Let’s say you have array of strings and want to remove all duplicate items. Meaning if you have this array:
let fruits = ["apple", "pear", "pear", "banana", "apple"]
You want each item only once.
let fruits = ["apple", "pear", "banana"]
The solution
If you know other collections in Swift, then you should know that Set
does not allow duplicates by default.
We can use this feature to our advantage and quickly remove the duplicates by first creating Set
from our Array
and then creating Array
once again:
let noDuplicates = Array(Set(fruits))
This is super short and works very well. It has one possibly big disadvantage and that is it loses the order of items. If you don’t care about order, then it does not matter. If you know how the items should be ordered then you can just call sorted
or sort
as a last step and solve it this way.
Keeping order
However in some cases you may get items from API that are ordered in particular way and you need to keep this ordering. Fortunately NSOrderedSet
comes to the rescue.
The NS
prefix betrays that this is not “native Swift” collection but we can use it regardless.
let orderedNoDuplicates = NSOrderedSet(array: fruits).map({ $0 as! String })
NSOrderedSet
is not generic so it works with type Any
. Meaning we are losing type safety, so we have to be careful about what items we are adding and getting back.
In the above case we know fruits
is array of strings so we can use as!
just fine to get back ordered strings without duplicates.
I would recommend using NSOrderedSet
only internally or creating wrapper struct around it with generic parameter to add type safety.
By the way since we are talking about sets, there is also NSCountedSet
that stores counts for elements.
Uses: Xcode 12 & Swift 5.3