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))} ??真的'(它更慢) –