Removing duplicate elements from an array in Swift

后端 未结 30 1996
遥遥无期
遥遥无期 2020-11-22 00:07

I might have an array that looks like the following:

[1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]

Or, reall

相关标签:
30条回答
  • 2020-11-22 00:50

    In case you need values sorted, this works (Swift 4)

    let sortedValues = Array(Set(array)).sorted()

    0 讨论(0)
  • 2020-11-22 00:52

    Swift 5

    extension Sequence where Element: Hashable {
        func unique() -> [Element] {
            NSOrderedSet(array: self as! [Any]).array as! [Element]
        }
    }
    
    0 讨论(0)
  • 2020-11-22 00:52

    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]
    
    0 讨论(0)
  • 2020-11-22 00:53

    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

    0 讨论(0)
  • 2020-11-22 00:54

    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
        }
    }
    
    0 讨论(0)
  • 2020-11-22 00:55

    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.

    0 讨论(0)
提交回复
热议问题