I might have an array that looks like the following:
[1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
Or, reall
In case you need values sorted, this works (Swift 4)
let sortedValues = Array(Set(array)).sorted()
extension Sequence where Element: Hashable {
func unique() -> [Element] {
NSOrderedSet(array: self as! [Any]).array as! [Element]
}
}
You can use directly a set collection to remove duplicate, then cast it back to an array
var myArray = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
var mySet = Set<Int>(myArray)
myArray = Array(mySet) // [2, 4, 60, 6, 15, 24, 1]
Then you can order your array as you want
myArray.sort{$0 < $1} // [1, 2, 4, 6, 15, 24, 60]
edit/update Swift 4 or later
We can also extend RangeReplaceableCollection
protocol to allow it to be used with StringProtocol
types as well:
extension RangeReplaceableCollection where Element: Hashable {
var orderedSet: Self {
var set = Set<Element>()
return filter { set.insert($0).inserted }
}
mutating func removeDuplicates() {
var set = Set<Element>()
removeAll { !set.insert($0).inserted }
}
}
let integers = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
let integersOrderedSet = integers.orderedSet // [1, 4, 2, 6, 24, 15, 60]
"abcdefabcghi".orderedSet // "abcdefghi"
"abcdefabcghi".dropFirst(3).orderedSet // "defabcghi"
Mutating method:
var string = "abcdefabcghi"
string.removeDuplicates()
string // "abcdefghi"
var substring = "abcdefabcdefghi".dropFirst(3) // "defabcdefghi"
substring.removeDuplicates()
substring // "defabcghi"
For Swift 3 click here
You can roll your own, e.g. like this:
func uniq<S : Sequence, T : Hashable>(source: S) -> [T] where S.Iterator.Element == T {
var buffer = [T]()
var added = Set<T>()
for elem in source {
if !added.contains(elem) {
buffer.append(elem)
added.insert(elem)
}
}
return buffer
}
let vals = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
let uniqueVals = uniq(vals) // [1, 4, 2, 6, 24, 15, 60]
And as an extension for Array
:
extension Array where Element: Hashable {
var uniques: Array {
var buffer = Array()
var added = Set<Element>()
for elem in self {
if !added.contains(elem) {
buffer.append(elem)
added.insert(elem)
}
}
return buffer
}
}
Swift 4
public extension Array where Element: Hashable {
func uniqued() -> [Element] {
var seen = Set<Element>()
return filter{ seen.insert($0).inserted }
}
}
every attempt to insert
will also return a tuple: (inserted: Bool, memberAfterInsert: Set.Element)
. See documentation.
Using the returned value helps us to avoid looping or doing any other operation.