我可能有一个像下面这样的数组:
[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是否提供了一种容易做到这一点的方法,还是我必须自己做?
当前回答
这只是一个非常简单和方便的实现。具有相等元素的数组扩展中的计算属性。
extension Array where Element: Equatable {
/// Array containing only _unique_ elements.
var unique: [Element] {
var result: [Element] = []
for element in self {
if !result.contains(element) {
result.append(element)
}
}
return result
}
}
其他回答
您总是可以使用Dictionary,因为Dictionary只能保存惟一的值。例如:
var arrayOfDates: NSArray = ["15/04/01","15/04/01","15/04/02","15/04/02","15/04/03","15/04/03","15/04/03"]
var datesOnlyDict = NSMutableDictionary()
var x = Int()
for (x=0;x<(arrayOfDates.count);x++) {
let date = arrayOfDates[x] as String
datesOnlyDict.setValue("foo", forKey: date)
}
let uniqueDatesArray: NSArray = datesOnlyDict.allKeys // uniqueDatesArray = ["15/04/01", "15/04/03", "15/04/02"]
println(uniqueDatesArray.count) // = 3
正如你所看到的,生成的数组并不总是按“顺序”排列。如果你想对数组排序,添加这个:
var sortedArray = sorted(datesOnlyArray) {
(obj1, obj2) in
let p1 = obj1 as String
let p2 = obj2 as String
return p1 < p2
}
println(sortedArray) // = ["15/04/01", "15/04/02", "15/04/03"]
.
如果你把两个扩展都放在你的代码中,更快的Hashable版本将在可能的情况下使用,Equatable版本将用作备用版本。
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<Hashable: Swift.Hashable>(
_ getHashable: (Element) -> Hashable
) -> [Element] {
var set: Set<Hashable> = []
return filter { set.insert(getHashable($0)).inserted }
}
/// The elements of the sequence, with "duplicates" removed,
/// based on a closure.
func firstUniqueElements<Equatable: Swift.Equatable>(
_ 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)
}
}
}
}
如果顺序不重要,那么你总是可以使用这个Set初始化式。
我创建了一个时间复杂度为o(n)的高阶函数。另外,像map这样的功能可以返回您想要的任何类型。
extension Sequence {
func distinct<T,U>(_ provider: (Element) -> (U, T)) -> [T] where U: Hashable {
var uniqueKeys = Set<U>()
var distintValues = [T]()
for object in self {
let transformed = provider(object)
if !uniqueKeys.contains(transformed.0) {
distintValues.append(transformed.1)
uniqueKeys.insert(transformed.0)
}
}
return distintValues
}
}
从数组中删除重复项的简单方法
extension Array where Element: Equatable {
mutating func removeDuplicates() {
var result = [Element]()
for value in self {
if !result.contains(value) {
result.append(value)
}
}
self = result
}}
Xcode 10.1 - Swift 4.2简单而强大的解决方案
func removeDuplicates(_ nums: inout [Int]) -> Int {
nums = Set(nums).sorted()
return nums.count
}
例子
var arr = [1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9]
removeDuplicates(&arr)
print(arr) // [1,2,3,4,5,6,7,8,9]