我编写了以下扩展来从我的数组中删除重复项。
extension Array where Element : Equatable{
func removeDups() -> [Element]{
var result = [Element]()
for element in self{
if !result.contains(element){
result.append(element)
}
}
return result
}
}
线阵
let linearArr = [1,2,2,3]
linearArr.removeDups() // [1,2,3] works well!
多维数组
let multiDimArr : [[Int]] = [[1,2,3], [1,2,3], [1,2 ,4]]
multiDimArr.removeDups() // Error!
Type [Int] does not conform to Equatable
我读了here .答案是使用 ==
进行数组比较应该有效。它并非一直有效:
有效
if (["1", "2"] == ["1", "2"]){
print("true")
}
不起作用
if ([1, 2] == [1, 2]){ // ERROR!
print("true")
}
Ambiguous use of operator '=='
这很奇怪。我可以比较 String
数组,但无法比较 Int
数组。
我还看到了this comment :
myArray1 == myArray2
的原因是NSObject
符合Equatable,调用-[equals:]
进行测试
不确定☝️评论是否仍然有效。
总结:
- 数组是否相等?我可以使用
==
比较它们吗
- 为什么比较
String
数组与Int
数组 - 如何从多维数组中删除重复项?
我目前正在使用 Swift 4.0.2
最佳答案
Are arrays equatable? Can I compare them using
==
在 Swift 4.1 之前,Array
不符合Equatable
.然而,==
过载了。将两个数组与 Equatable
进行比较元素,这是使它能够编译的原因:
if ["1", "2"] == ["1", "2"] { // using <T : Equatable>(lhs: [T], rhs: [T]) -> Bool
print("true")
}
但是在 Swift 4.1(Xcode 9.3 可用)中,Array<Element>
现在符合 Equatable
当它 Element
符合 Equatable
.此更改is given in the changelog :
Swift 4.1
[...]
- SE-0143 The standard library types
Optional
,Array
,ArraySlice
,ContiguousArray
, andDictionary
now conform to theEquatable
protocol when their element types conform toEquatable
. This allows the==
operator to compose (e.g., one can compare two values of type[Int : [Int?]?]
with==
), as well as use various algorithms defined forEquatable
element types, such asindex(of:)
.
你的例子 multiDimArr.removeDups()
在 4.1 中按预期编译和运行,产生结果 [[1, 2, 3], [1, 2, 4]]
.
在 Swift 4.0.3 中,您可以通过添加另一个重载 removeDups()
来破解它。对于嵌套数组:
extension Array {
func removeDups<T : Equatable>() -> [Element] where Element == [T] {
var result = [Element]()
for element in self{
if !result.contains(where: { element == $0 }) {
result.append(element)
}
}
return result
}
}
let multiDimArr = [[1, 2, 3], [1, 2, 3], [1, 2, 4]]
print(multiDimArr.removeDups()) // [[1, 2, 3], [1, 2, 4]]
不幸的是,这确实会导致一些代码重复,但至少您可以在更新到 4.1 时摆脱它。
这个例子不能在 4.0.3 或 4.1 中编译的事实:
if [1, 2] == [1, 2] { // error: Ambiguous use of operator '=='
print("true")
}
是由于错误 SR-5944 – 由于 ==
,编译器认为它不明确IndexSet
的重载和 IndexPath
(两者都是 ExpressibleByArrayLiteral
)。但是 Swift 应该将数组文字默认为 Array
虽然,解决了歧义。
要么说:
if [1, 2] as [Int] == [1, 2] {
print("true")
}
或不导入 Foundation
解决了这个问题。
最后,值得注意的是 removeDups()
的性能如果 Element
可以改进类型也是 Hashable
,允许它以线性而不是二次时间运行:
extension Array where Element : Hashable {
func removeDups() -> [Element] {
var uniquedElements = Set<Element>()
return filter { uniquedElements.insert($0).inserted }
}
}
这里我们使用一个集合来存储我们已经看到的元素,省略了我们已经插入其中的任何元素。这也允许我们使用 filter(_:)
, as @Alexander points out .
和in Swift 4.2 , Array
也有条件地符合 Hashable
当它 Element
是Hashable
:
Swift 4.2
[...]
- SE-0143 The standard library types
Optional
,Array
,ArraySlice
,ContiguousArray
,Dictionary
,DictionaryLiteral
,Range
, andClosedRange
now conform to theHashable
protocol when their element or bound types (as the case may be) conform toHashable
. This makes synthesizedHashable
implementations available for types that include stored properties of these types.
关于arrays - 从多维数组中删除重复项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50275692/