我可能有一个像下面这样的数组:
[1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
或者,实际上,任何类似类型的数据部分的序列。我要做的是确保每个相同的元素只有一个。例如,上面的数组将变成:
[1, 4, 2, 6, 24, 15, 60]
请注意,删除了2、6和15的重复项,以确保每个相同的元素中只有一个。Swift是否提供了一种容易做到这一点的方法,还是我必须自己做?
我可能有一个像下面这样的数组:
[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
其他回答
这是swift 4.2中最简单的方法,如下所示的代码
let keyarray:NSMutableArray = NSMutableArray()
for object in dataArr
{
if !keysArray.contains(object){
keysArray.add(object)
}
}
print(keysArray)
下面是使用自定义匹配函数使序列唯一的更灵活的方法。
extension Sequence where Iterator.Element: Hashable {
func unique(matching: (Iterator.Element, Iterator.Element) -> Bool) -> [Iterator.Element] {
var uniqueArray: [Iterator.Element] = []
forEach { element in
let isUnique = uniqueArray.reduce(true, { (result, item) -> Bool in
return result && matching(element, item)
})
if isUnique {
uniqueArray.append(element)
}
}
return uniqueArray
}
}
你可以很容易地转换为一个Set和一个数组:
let unique = Array(Set(originals))
这并不能保证保持数组的原始顺序。
斯威夫特4
保证继续订购。
extension Array where Element: Equatable {
func removingDuplicates() -> Array {
return reduce(into: []) { result, element in
if !result.contains(element) {
result.append(element)
}
}
}
}
我使用了@Jean-Philippe Pellet的答案,并做了一个数组扩展,对数组进行类似set的操作,同时保持元素的顺序。
/// Extensions for performing set-like operations on lists, maintaining order
extension Array where Element: Hashable {
func unique() -> [Element] {
var seen: [Element:Bool] = [:]
return self.filter({ seen.updateValue(true, forKey: $0) == nil })
}
func subtract(takeAway: [Element]) -> [Element] {
let set = Set(takeAway)
return self.filter({ !set.contains($0) })
}
func intersect(with: [Element]) -> [Element] {
let set = Set(with)
return self.filter({ set.contains($0) })
}
}