7
Swift中是否有函数检查数组中的所有元素是否具有相同的值?在我的情况下,它是一个Int
类型的数组。我知道我可以使用一个简单的for循环遍历它我只是想知道是否有内置的东西,更快。检查数组中的所有元素是否具有相同的值Swift
Swift中是否有函数检查数组中的所有元素是否具有相同的值?在我的情况下,它是一个Int
类型的数组。我知道我可以使用一个简单的for循环遍历它我只是想知道是否有内置的东西,更快。检查数组中的所有元素是否具有相同的值Swift
任何方法必须遍历所有元素,直到一个不同的元素被发现:
func allEqualUsingLoop<T : Equatable>(array : [T]) -> Bool {
if let firstElem = array.first {
for elem in array {
if elem != firstElem {
return false
}
}
}
return true
}
而是外在的循环,你可以使用功能:
func allEqualUsingContains<T : Equatable>(array : [T]) -> Bool {
if let firstElem = array.first {
return !contains(array, { $0 != firstElem })
}
return true
}
如果数组元素是Hashable
(如Int
),那么你可以 从数组元素中创建一个Set
(从Swift 1.2开始可用),并检查它是否只有一个元素。
func allEqualUsingSet<T : Hashable>(array : [T]) -> Bool {
let uniqueElements = Set(array)
return count(uniqueElements) <= 1
}
快速基准测试表明,“包含”方法比“置位”方法 快得多为百万个整数的数组,特别是如果元件是 不全部相等。这是有意义的,因为尽快返回 作为找到的不匹配元素,而Set(array)
总是 遍历整个数组。
此外,“contains”方法与显式循环同样快或略快。
这是一些简单的基准测试代码。当然结果可以变化 与数组大小,不同元素的数量和元素数据类型。
func measureExecutionTime<T>(title: String, @noescape f : (() -> T)) -> T {
let start = NSDate()
let result = f()
let end = NSDate()
let duration = end.timeIntervalSinceDate(start)
println("\(title) \(duration)")
return result
}
var array = [Int](count: 1_000_000, repeatedValue: 1)
array[500_000] = 2
let b1 = measureExecutionTime("using loop ") {
return allEqualUsingLoop(array)
}
let b2 = measureExecutionTime("using contains") {
allEqualUsingContains(array)
}
let b3 = measureExecutionTime("using set ") {
allEqualUsingSet(array)
}
结果(在MacBook Pro上,推出配置):
using loop 0.000651001930236816 using contains 0.000567018985748291 using set 0.0344770550727844
随着array[1_000] = 2
结果是
using loop 9.00030136108398e-06 using contains 2.02655792236328e-06 using set 0.0306439995765686
更新夫特2/Xcode中7:由于Swift 语法的各种更改,该功能现在写成
func allEqual<T : Equatable>(array : [T]) -> Bool {
if let firstElem = array.first {
return !array.dropFirst().contains { $0 != firstElem }
}
return true
}
但你现在也可以将它定义为数组的扩展方法:
extension Array where Element : Equatable {
func allEqual() -> Bool {
if let firstElem = first {
return !dropFirst().contains { $0 != firstElem }
}
return true
}
}
print([1, 1, 1].allEqual()) // true
print([1, 2, 1].allEqual()) // false
试图同...编译器检查;-) – Antonio
@Antonio:好,谢谢! –
如果你有兴趣试试另一个,你可以使用'equal'和'Repeat':'array.first.map {equal(array,Repeat(count:array.count,repeatedValue:$ 0))} ??真的'(它更慢) –