BlogRemoving duplicate elements from a Swift array
Removing duplicate elements from a Swift array
Today I had to remove duplicate items from an Array while maintaining the original order. I knew there was no standard uniq function in Swift so I Googled a bit and found some implementations on StackOverflow. I found some good implementations, but wasn’t completely satisfied with any of them. So of course I tried to see if I could make something myself that I would be satisfied with.
The main issue I had with everything I found was that they all created a unique copy of the Array. Arrays are structs, and variable structs can be mutated. Therefore I wanted to have a function that would mutate an Array and remove duplicate elements rather than give me a copy without the duplicate entries. But of course, a copy has to be possible as well, in case we’re dealing with a constant let Array.
Here is the solution I came up with:
extension Array where Element: Equatable {
public func uniq() -> [Element] {
var arrayCopy = self
arrayCopy.uniqInPlace()
return arrayCopy
}
mutating public func uniqInPlace() {
var seen = [Element]()
var index = 0
for element in self {
if seen.contains(element) {
removeAtIndex(index)
} else {
seen.append(element)
index++
}
}
}
}
This mutating “in place” function and the non-mutating copying function are matching the sort() and sortInPlace() functions that come with Swift so it should be clear to developers as to what they do. Just keep in mind that this version only works for elements that are Equatable.
Here are some examples of using it with both a variable and constant array:
var numbers = [1, 6, 2, 2, 4, 1, 5]
numbers.uniqInPlace()
// numbers is now [1, 6, 2, 4, 5]
let strings = ["Y", "Z", "A", "Y", "B", "Y", "Z"]
let uniqStrings = strings.uniq()
// uniqStrings is now ["Y", "Z", "A", "B"]
I’d love to hear feedback and if anyone has any other (better) ideas for a uniq and uniqInPlace implementation.