我可能有一个像下面这样的数组:
[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是否提供了一种容易做到这一点的方法,还是我必须自己做?
当前回答
这是swift 4.2中最简单的方法,如下所示的代码
let keyarray:NSMutableArray = NSMutableArray()
for object in dataArr
{
if !keysArray.contains(object){
keysArray.add(object)
}
}
print(keysArray)
其他回答
斯威夫特4
保证继续订购。
extension Array where Element: Equatable {
func removingDuplicates() -> Array {
return reduce(into: []) { result, element in
if !result.contains(element) {
result.append(element)
}
}
}
}
最简单的方法是使用NSOrderedSet,它存储唯一的元素并保持元素的顺序。如:
func removeDuplicates(from items: [Int]) -> [Int] {
let uniqueItems = NSOrderedSet(array: items)
return (uniqueItems.array as? [Int]) ?? []
}
let arr = [1, 4, 2, 2, 6, 24, 15, 2, 60, 15, 6]
removeDuplicates(from: arr)
下面是SequenceType上的一个类别,它保留了数组的原始顺序,但使用Set来进行contains查找,以避免数组的contains(_:)方法上的O(n)代价。
public extension Sequence where Element: Hashable {
/// Return the sequence with all duplicates removed.
///
/// i.e. `[ 1, 2, 3, 1, 2 ].uniqued() == [ 1, 2, 3 ]`
///
/// - note: Taken from stackoverflow.com/a/46354989/3141234, as
/// per @Alexander's comment.
func uniqued() -> [Element] {
var seen = Set<Element>()
return self.filter { seen.insert($0).inserted }
}
}
如果你不是Hashable或Equatable,你可以传入一个谓词来进行相等性检查:
extension Sequence {
/// Return the sequence with all duplicates removed.
///
/// Duplicate, in this case, is defined as returning `true` from `comparator`.
///
/// - note: Taken from stackoverflow.com/a/46354989/3141234
func uniqued(comparator: @escaping (Element, Element) throws -> Bool) rethrows -> [Element] {
var buffer: [Element] = []
for element in self {
// If element is already in buffer, skip to the next element
if try buffer.contains(where: { try comparator(element, $0) }) {
continue
}
buffer.append(element)
}
return buffer
}
}
现在,如果你没有Hashable,但是是Equatable,你可以使用这个方法:
extension Sequence where Element: Equatable {
/// Return the sequence with all duplicates removed.
///
/// i.e. `[ 1, 2, 3, 1, 2 ].uniqued() == [ 1, 2, 3 ]`
///
/// - note: Taken from stackoverflow.com/a/46354989/3141234
func uniqued() -> [Element] {
return self.uniqued(comparator: ==)
}
}
最后,你可以添加一个unique的关键路径版本,如下所示:
extension Sequence {
/// Returns the sequence with duplicate elements removed, performing the comparison using the property at
/// the supplied keypath.
///
/// i.e.
///
/// ```
/// [
/// MyStruct(value: "Hello"),
/// MyStruct(value: "Hello"),
/// MyStruct(value: "World")
/// ].uniqued(\.value)
/// ```
/// would result in
///
/// ```
/// [
/// MyStruct(value: "Hello"),
/// MyStruct(value: "World")
/// ]
/// ```
///
/// - note: Taken from stackoverflow.com/a/46354989/3141234
///
func uniqued<T: Equatable>(_ keyPath: KeyPath<Element, T>) -> [Element] {
self.uniqued { $0[keyPath: keyPath] == $1[keyPath: keyPath] }
}
}
你可以把这两个都放在你的应用程序中,Swift会根据你的序列的迭代器选择正确的一个。元素类型。
对于El Capitan,您可以扩展此方法以包括多个键盘,如下所示:
/// Returns the sequence with duplicate elements removed, performing the comparison using the property at
/// the supplied keypaths.
///
/// i.e.
///
/// ```
/// [
/// MyStruct(value1: "Hello", value2: "Paula"),
/// MyStruct(value1: "Hello", value2: "Paula"),
/// MyStruct(value1: "Hello", value2: "Bean"),
/// MyStruct(value1: "World", value2: "Sigh")
/// ].uniqued(\.value1, \.value2)
/// ```
/// would result in
///
/// ```
/// [
/// MyStruct(value1: "Hello", value2: "Paula"),
/// MyStruct(value1: "Hello", value2: "Bean"),
/// MyStruct(value1: "World", value2: "Sigh")
/// ]
/// ```
///
/// - note: Taken from stackoverflow.com/a/46354989/3141234
///
func uniqued<T: Equatable, U: Equatable>(_ keyPath1: KeyPath<Element, T>, _ keyPath2: KeyPath<Element, U>) -> [Element] {
self.uniqued {
$0[keyPath: keyPath1] == $1[keyPath: keyPath1] && $0[keyPath: keyPath2] == $1[keyPath: keyPath2]
}
}
但是(恕我直言)你最好把你自己的block传递给self.unique。
斯威夫特4. x:
extension Sequence where Iterator.Element: Hashable {
func unique() -> [Iterator.Element] {
return Array(Set<Iterator.Element>(self))
}
func uniqueOrdered() -> [Iterator.Element] {
return reduce([Iterator.Element]()) { $0.contains($1) ? $0 : $0 + [$1] }
}
}
用法:
["Ljubljana", "London", "Los Angeles", "Ljubljana"].unique()
or
["Ljubljana", "London", "Los Angeles", "Ljubljana"].uniqueOrdered()
在Swift 3.0中,我发现了最简单和最快的解决方案,可以在保持顺序的同时消除重复的元素:
extension Array where Element:Hashable {
var unique: [Element] {
var set = Set<Element>() //the unique list kept in a Set for fast retrieval
var arrayOrdered = [Element]() //keeping the unique list of elements but ordered
for value in self {
if !set.contains(value) {
set.insert(value)
arrayOrdered.append(value)
}
}
return arrayOrdered
}
}