Removing duplicate elements from an array in Swift

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

    If you put both extensions in your code, the faster Hashable version will be used when possible, and the Equatable version will be used as a fallback.

    public extension Sequence where Element: Hashable {
      /// The elements of the sequence, with duplicates removed.
      /// - Note: Has equivalent elements to `Set(self)`.
      @available(
      swift, deprecated: 5.4,
      message: "Doesn't compile without the constant in Swift 5.3."
      )
      var firstUniqueElements: [Element] {
        let getSelf: (Element) -> Element = \.self
        return firstUniqueElements(getSelf)
      }
    }
    
    public extension Sequence where Element: Equatable {
      /// The elements of the sequence, with duplicates removed.
      /// - Note: Has equivalent elements to `Set(self)`.
      @available(
      swift, deprecated: 5.4,
      message: "Doesn't compile without the constant in Swift 5.3."
      )
      var firstUniqueElements: [Element] {
        let getSelf: (Element) -> Element = \.self
        return firstUniqueElements(getSelf)
      }
    }
    
    public extension Sequence {
      /// The elements of the sequences, with "duplicates" removed
      /// based on a closure.
      func firstUniqueElements(
        _ getHashable: (Element) -> Hashable
      ) -> [Element] {
        var set: Set = []
        return filter { set.insert(getHashable($0)).inserted }
      }
    
      /// The elements of the sequence, with "duplicates" removed,
      /// based on a closure.
      func firstUniqueElements(
        _ getEquatable: (Element) -> Equatable
      ) -> [Element] {
        reduce(into: []) { uniqueElements, element in
          if zip(
            uniqueElements.lazy.map(getEquatable),
            AnyIterator { [equatable = getEquatable(element)] in equatable }
          ).allSatisfy(!=) {
            uniqueElements.append(element)
          }
        }
      }
    }
    

    If order isn't important, then you can always just use this Set initializer.

提交回复
热议问题