在swift中比较数组
试图了解如何迅速比较数组。
var myArray1 : [String] = ["1","2","3","4","5"] var myArray2 : [String] = ["1","2","3","4","5"] // 1) Comparing 2 simple arrays if(myArray1 == myArray2) { println("Equality") } else { println("Equality no") } // -> prints equality -> thanks god // 2) comparing to a "copy" of an array // swift copies arrays when passed as parameters (as per doc) func arrayTest(anArray: [String]) -> Bool { return anArray == myArray1 } println("Array test 1 is \(arrayTest(myArray1))") println("Array test 2 is \(arrayTest(myArray2))") // equality works for both myArray2.append("test") println("Array test 2 is \(arrayTest(myArray2))") // false (obviously) myArray2.removeAtIndex(5) println("Array test 2 is \(arrayTest(myArray2))") // true
苹果表示,在arrays副本的背景下有优化。 看起来像有时 – 并不总是 – 结构实际上是复制或不。
这就是说,
1)是==迭代所有的数组来执行基于元素的比较? (看起来像) – >如何在性能/内存非常大的数组呢?
2)如果所有元素都相等,我们是否肯定==会返回true? 我对Javastring有不好的回忆
3)有没有办法来检查myArray1和myArray2技术上是否使用相同的“内存位置”/指针/等? 我了解了优化如何工作和潜在的警告。
谢谢。
你对==
稍微有些紧张:
struct NeverEqual: Equatable { } func ==(lhs: NeverEqual, rhs: NeverEqual)->Bool { return false } let x = [NeverEqual()] var y = x x == y // this returns true [NeverEqual()] == [NeverEqual()] // false x == [NeverEqual()] // false let z = [NeverEqual()] x == z // false x == y // true y[0] = NeverEqual() x == y // now false
为什么? Swift数组不符合Equatable
,但他们有一个==
运算符,在标准库中定义为:
func ==<T : Equatable>(lhs: [T], rhs: [T]) -> Bool
这个运算符遍历lhs
和rhs
的元素,比较每个位置的值。 它不会执行按位比较 – 它会在每对元素上调用==
运算符。 这意味着如果你为你的元素写一个自定义==
,它会被调用。
但是它包含一个优化 – 如果两个数组的底层缓冲区是相同的,那么它不会感到困扰,它只是返回true(它们包含相同的元素,当然它们是相等的!)。
这个问题完全是NeverEqual
相等运算符的错误。 平等应该是传递的,对称的和自反的,而这个不是自反的( x == x
是错误的)。 但它可能仍然不了解你。
Swift数组是写时复制的 – 所以当你写var x = y
它实际上并不复制数组,它只是指向x
的存储缓冲区指针。 只有当x
或y
稍后发生变化时,才会创build缓冲区的副本,以便未改变的variables不受影响。 这对数组的行为类似于值types而言至关重要,但仍然是高性能的。
在Swift的早期版本中,实际上可以在数组上调用===
(在早期版本中,变异行为有点不同,如果你变异了x
, y
也会变化,即使它已经被声明为let
-所以他们改变了)。
你可以在数组中复制===
的旧行为(除了捅破和刺激调查之外,非常依赖于实现)
let a = [1,2,3] var b = a a.withUnsafeBufferPointer { outer in b.withUnsafeBufferPointer { inner in println(inner.baseAddress == outer.baseAddress) } }
Swift中的==
与Java的equals()
,它比较值。
在Swift中===
与Java的==
相同,它比较引用。
在Swift中,您可以比较数组内容值,如下所示:
["1", "2"] == ["1", "2"]
但是如果你想比较引用,这将不起作用:
var myArray1 = [NSString(string: "1")] var myArray2 = [NSString(string: "1")] myArray1[0] === myArray2[0] // false myArray1[0] == myArray2[0] // true
所以答案是:
- 我认为性能是做价值(而不是参考)比较的最佳select
- 是的,如果你想比较值
- Swift数组是值types而不是引用types。 所以只有当你比较自己的内存位置(或使用不安全的指针)
这取决于你如何比较。 例如: ["1", "2"] == ["1", "2"] // true
但是["1", "2"] == ["2", "1"] // false
如果你需要第二种情况也是正确的,可以忽略重复值,你可以这样做: Set(["1", "2"]) == Set(["2", "1"]) // true
(使用NSSet for Swift 2)