arrays - 快速比较数组

标签 arrays swift comparison

试图了解 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

Apple 表示阵列副本在幕后进行了优化。看起来有时 - 并非总是 - 结构实际上是否被复制。

也就是说,

1) 是否 == 遍历所有数组以执行基于元素的比较? (看起来像) -> 那么在非常大的阵列上性能/内存使用情况如何?

2) 如果所有元素都相等,我们确定 == 会返回 true 吗?我对 Java 字符串上的 == 有不好的记忆

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

此运算符遍历 lhsrhs 中的元素,比较每个位置的值。它进行按位比较——它在每对元素上调用== 运算符。这意味着如果您为元素编写自定义 ==,它将被调用。

但它包含一个优化——如果两个数组的底层缓冲区相同,它不会打扰,它只是返回 true(它们包含相同的元素,当然它们是相等的!)。

这个问题完全是 NeverEqual 相等运算符的错误。平等应该是传递的、对称的和自反的,而这个不是自反的(x == x 是 false)。但它仍然会让你措手不及。

Swift 数组是写时复制的——所以当你写 var x = y 它实际上并没有复制数组,它只是指向 xy 的存储缓冲区指针。仅当 xy 稍后发生变异时,它才会制作缓冲区的副本,以便未更改的变量不受影响。这对于数组表现得像值类型但仍然具有高性能至关重要。

在 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) 
    } 
}

关于arrays - 快速比较数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27567736/

相关文章:

python - 从矩阵中找到第一个匹配子矩阵的快速方法

php - 从 ids 数组生成唯一的固定整数 ids

python - 从python数组中分割偶数/奇数行的最短方法?

swift - 如何使用 firebase 在 swift 中将自定义登录名(电子邮件)与 Facebook 登录名合并

java - 在 Java 中实现 SIFT

python - Twisted 有什么了不起的?

python - 无法将线程追加到数组

javascript - 如何在javascript中找到两个不不同数组的差异?我使用了下划线,但我对普通 JS 持开放态度

swift - 如何在不将密码放入 Vapor 3 的 configure.swift 的情况下配置 Fluent/MySQL 数据库连接?

ios - UICollectionViewListCell 的自定义子类中的自调整大小在 iOS 14 中不起作用