[英]How can I get all unique elements from a collection in Swift
请注意,您需要导入 Foundation 才能使用 NSCountedSet。 如果你需要一个纯粹的迅速解决,以找到一个集合的独特元素,你可以扩展它制约因素的Equatable协议和检查,如果你不能找到元素指数,如果指数(作者:元)再次检查零使用的== index(after:) 元素索引作为集合子序列的startIndex:
编辑/更新: Swift 4.2.1
请注意,扩展 RangeReplacebleCollection 它将涵盖 StringProtocol 类型String
和Substring
以及:
将元素约束为Equatable
Xcode 11 • Swift 5.1
extension RangeReplaceableCollection where Element: Equatable {
var uniqueElements: Self {
filter { self[index(after: firstIndex(of: $0)!)...].firstIndex(of: $0) == nil }
}
mutating func removeAllNonUniqueElements() { self = uniqueElements }
}
如果您不需要保持集合的原始顺序,您可以利用新的 Dictionary 初始值设定项,但这需要将元素限制为Hashable
:
init<S>(grouping values: S, by keyForValue: (S.Element) throws -> Dictionary<Key, Value>.Key) rethrows where Value == [S.Element], S : Sequence
并保留值等于 1 的键
extension RangeReplaceableCollection where Element: Hashable {
var uniqueElementsSet: Set<Element> {
Set(Dictionary(grouping: self, by: { $0 }).compactMap{ $1.count == 1 ? $0 : nil })
}
}
游乐场测试
let numbers = [0, 0, 1, 1, 1, 2, 3, 4, 5, 5]
numbers.uniqueElements // [4, 2, 3]
如果您需要保持集合的顺序,您可以获取此答案中所示的元素频率并过滤唯一元素:
extension Sequence where Element: Hashable {
var frequency: [Element: Int] { reduce(into: [:]) { $0[$1, default: 0] += 1 } }
}
extension RangeReplaceableCollection where Element: Hashable {
var uniqueElements: Self { filter { frequency[$0] == 1 } }
mutating func removeAllNonUniqueElements() { self = uniqueElements }
}
游乐场测试
let numbers = [0, 0, 1, 1, 1, 2, 3, 4, 5, 5]
numbers.uniqueElements // [2, 3, 4]
var string = "0011123455"
string.uniqueElements // "234"
string.uniqueElementsSet // {"4", "3", "2"}
print(string) // "0011123455\n"
// mutating the string
string.removeAllNonUniqueElements()
print(string) // 234
如果您只想过滤出现 1 次的数字,您可以使用旧的NSCountedSet
let nums = [0, 0, 1, 1, 1, 2, 3, 4, 5, 5]
let countedSet = NSCountedSet(array: nums)
let uniques = nums.filter { countedSet.count(for: $0) == 1 }
print(uniques) // [2, 3, 4]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.