数组是等价的吗?我可以使用它们进行比较吗==
在 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>符合. 此更改在更改日志中给出:EquatableElementEquatable
斯威夫特 4.1
[...]
- SE-0143标准库类型
Optional, Array, ArraySlice,ContiguousArray和Dictionary现在Equatable在其元素类型符合时符合协议Equatable。这允许==操作员进行组合(例如,可以将两个类型的值[Int : [Int?]?]与进行比较==),以及使用为Equatable元素类型定义的各种算法,例如index(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造成的——编译器认为它是模棱两可的,因为and (两者都是)的==重载。但是 Swift 应该默认一个数组字面量来解决歧义。IndexSetIndexPathExpressibleByArrayLiteralArray
说:
if [1, 2] as [Int] == [1, 2] {
print("true")
}
或不导入Foundation解决问题。
最后,值得注意的是,如果类型也是,removeDups()则可以提高的性能,允许它以线性时间而不是二次时间运行:ElementHashable
extension Array where Element : Hashable {
func removeDups() -> [Element] {
var uniquedElements = Set<Element>()
return filter { uniquedElements.insert($0).inserted }
}
}
在这里,我们使用一个集合来存储我们已经看到的元素,省略了我们已经插入其中的任何元素。正如@Alexander 指出的那样filter(_:),这也允许我们使用。
而在 Swift 4.2中,Array也有条件地符合Hashablewhen it Elementis Hashable:
斯威夫特 4.2
[...]
- SE-0143标准库类型
Optional, Array, ArraySlice, ContiguousArray, Dictionary, DictionaryLiteral, Range, 和ClosedRange现在Hashable在其元素或绑定类型(视情况而定)符合时符合协议Hashable。这使得综合Hashable实现可用于包含这些类型的存储属性的类型。