How to quickly remove duplicates from Array & keep order

Removing duplicates is swift in Swift thanks to the Set type. We can also leverage NSOrderedSet to not lose order of the items.

The 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 11 & Swift 5