Removing duplicate elements from an array in Swift

后端 未结 30 1993
遥遥无期
遥遥无期 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:35

    An alternate (if not optimal) solution from here using immutable types rather than variables:

    func deleteDuplicates<S: ExtensibleCollectionType where S.Generator.Element: Equatable>(seq:S)-> S {
        let s = reduce(seq, S()){
            ac, x in contains(ac,x) ? ac : ac + [x]
        }
        return s
    }
    

    Included to contrast Jean-Pillippe's imperative approach with a functional approach.

    As a bonus this function works with strings as well as arrays!

    Edit: This answer was written in 2014 for Swift 1.0 (before Set was available in Swift). It doesn't require Hashable conformance & runs in quadratic time.

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

    Swift 4.x:

    extension Sequence where Iterator.Element: Hashable {
      func unique() -> [Iterator.Element] {
        return Array(Set<Iterator.Element>(self))
      }
    
      func uniqueOrdered() -> [Iterator.Element] {
        return reduce([Iterator.Element]()) { $0.contains($1) ? $0 : $0 + [$1] }
      }
    }
    

    usage:

    ["Ljubljana", "London", "Los Angeles", "Ljubljana"].unique()
    

    or

    ["Ljubljana", "London", "Los Angeles", "Ljubljana"].uniqueOrdered()
    
    0 讨论(0)
  • 2020-11-22 00:35
    1. First add all the elements of an array to NSOrderedSet.
    2. This will remove all the duplicates in your array.
    3. Again convert this orderedset to an array.

    Done....

    Example

    let array = [1,1,1,1,2,2,2,2,4,6,8]
    
    let orderedSet : NSOrderedSet = NSOrderedSet(array: array)
    
    let arrayWithoutDuplicates : NSArray = orderedSet.array as NSArray
    

    output of arrayWithoutDuplicates - [1,2,4,6,8]

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

    You can convert to a Set and back to an Array again quite easily:

    let unique = Array(Set(originals))
    

    This is not guaranteed to maintain the original order of the array.

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

    Many answers available here, but I missed this simple extension, suitable for Swift 2 and up:

    extension Array where Element:Equatable {
        func removeDuplicates() -> [Element] {
            var result = [Element]()
    
            for value in self {
                if result.contains(value) == false {
                    result.append(value)
                }
            }
    
            return result
        }
    }
    

    Makes it super simple. Can be called like this:

    let arrayOfInts = [2, 2, 4, 4]
    print(arrayOfInts.removeDuplicates()) // Prints: [2, 4]
    

    Filtering based on properties

    To filter an array based on properties, you can use this method:

    extension Array {
    
        func filterDuplicates(@noescape includeElement: (lhs:Element, rhs:Element) -> Bool) -> [Element]{
            var results = [Element]()
    
            forEach { (element) in
                let existingElements = results.filter {
                    return includeElement(lhs: element, rhs: $0)
                }
                if existingElements.count == 0 {
                    results.append(element)
                }
            }
    
            return results
        }
    }
    

    Which you can call as followed:

    let filteredElements = myElements.filterDuplicates { $0.PropertyOne == $1.PropertyOne && $0.PropertyTwo == $1.PropertyTwo }
    
    0 讨论(0)
  • 2020-11-22 00:38

    swift 2

    with uniq function answer:

    func uniq<S: SequenceType, E: Hashable where E==S.Generator.Element>(source: S) -> [E] {
        var seen: [E:Bool] = [:]
        return source.filter({ (v) -> Bool in
            return seen.updateValue(true, forKey: v) == nil
        })
    }
    

    use:

    var test = [1,2,3,4,5,6,7,8,9,9,9,9,9,9]
    print(uniq(test)) //1,2,3,4,5,6,7,8,9
    
    0 讨论(0)
提交回复
热议问题