我可能有一个像下面这样的数组:

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

或者,实际上,任何类似类型的数据部分的序列。我要做的是确保每个相同的元素只有一个。例如,上面的数组将变成:

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

请注意,删除了2、6和15的重复项,以确保每个相同的元素中只有一个。Swift是否提供了一种容易做到这一点的方法,还是我必须自己做?


当前回答

正如WWDC 2021所指出的那样,Swift有社区开发的算法、集合和数字包。算法包有一个唯一的()算法。

这些还不是Swift标准库的一部分。你目前可以从苹果的Github页面下载它们和/或通过Swift软件包管理器安装它们。

WWDC视频:

https://developer.apple.com/videos/play/wwdc2021/10256/

Github页面:

https://github.com/apple/swift-algorithms

unique()和unique (on:)文档:

https://github.com/apple/swift-algorithms/blob/main/Guides/Unique.md

其他回答

我相信提供一个uniq()和uniqInPlace()函数通过删除数组的值来改变数组是很好的。这类似于Swift提供的sort()和sortInPlace()函数。此外,由于它是一个数组,它应该保持它的原始元素顺序。

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++
            }
        }
    }
}

你只能在变量数组(即var)上使用uniqInPlace(),因为你不能改变常量数组(即let)。

一些用法示例:

var numbers = [1, 6, 2, 2, 4, 1, 5]
numbers.uniqInPlace() // array 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"]

在数组中保留唯一值和排序。

(使用Swift 3)

    var top3score: [Int] = []


    outerLoop: for i in 0..<top10score.count {
        dlog(message: String(top10score[i]))

        if top3score.count == 3 {
            break
        }

        for aTop3score in top3score {
            if aTop3score == top10score[i] {
                continue outerLoop
            }
        }

        top3score.append(top10score[i])

    }

    print("top10score is \(top10score)")  //[14, 5, 5, 5, 3, 3, 2, 2, 2, 2]
    print("top3score is \(top3score)")   //[14, 5, 3]

我认为这是更好的理解逻辑的方法

var arrayOfInts = [2, 2, 4, 4]
var mainArray = [Int]()

for value in arrayOfInts {

if mainArray.contains(value) != true  {
    
    mainArray.append(value)
    print("mainArray:\(mainArray)")
}}

斯威夫特4

public extension Array where Element: Hashable {
    func uniqued() -> [Element] {
        var seen = Set<Element>()
        return filter{ seen.insert($0).inserted }
    }
}

每次尝试插入也将返回一个元组:(插入:Bool, memberAfterInsert: Set.Element)。见文档。

使用返回值意味着我们可以避免进行多个循环,因此这是O(n)。

编辑/更新Swift 4或更高版本

我们还可以扩展RangeReplaceableCollection协议,以允许它也用于StringProtocol类型:

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"

变异的方法:

var string = "abcdefabcghi"
string.removeDuplicates() 
string  //  "abcdefghi"

var substring = "abcdefabcdefghi".dropFirst(3)  // "defabcdefghi"
substring.removeDuplicates()
substring   // "defabcghi"

对于Swift 3,请点击这里