我正在讀取包含鍵/值行到Swift結構中的文本文件。文件的其中一行在行中有五個空格分隔的值,我使用componentsSeparatedByString轉換爲數組。將字符串數組複製到一個整數數組?
的實際值是整數,所以正常的解決辦法是遍歷每一個,並將其複製到我的結構的int數組中相關聯的槽。但是我在這裏錯過了一些Swift(或基礎)魔法?
我正在讀取包含鍵/值行到Swift結構中的文本文件。文件的其中一行在行中有五個空格分隔的值,我使用componentsSeparatedByString轉換爲數組。將字符串數組複製到一個整數數組?
的實際值是整數,所以正常的解決辦法是遍歷每一個,並將其複製到我的結構的int數組中相關聯的槽。但是我在這裏錯過了一些Swift(或基礎)魔法?
可以使用map
功能,它通過陣列中的所有元素循環和轉化適用於你傳遞給它一個定義封閉的每個元素。
var array = ["2", "4", "6", "8"]
let ints = array.map { $0.toInt()! }
請注意,我使用強制轉換成整數的時候展開 - 這樣使用它,如果你是100%肯定的陣列中的所有元素其實都是整數,否則運行時異常會產生
更安全方法是映射到可選的整數,然後過濾以去除零值,然後再映射到迫使展開自選:
let ints = array.map { $0.toInt() }.filter { $0 != nil }.map { $0! }
注意,這更安全的版本可能看起來比使用for
循環變慢(實際上是,因爲它遍歷該陣列的3倍 - 除非編譯器能夠優化它) - 但我寧願它在一個循環,因爲它在我看來更具可讀性更加緊湊和。不用說,儘管如此,我不太可能使用大型數組。
附錄:由@MikeS的建議,它可以使用reduce
最後兩個步驟的更安全版本相結合:
let ints = array.map { $0.toInt() }.reduce([]) { $1 != nil ? $0 + [$1!] : $0 }
它看起來像小型陣列的一個很好的選擇,因爲它降低了從O(3n)到O(2n)的複雜度 - 儘管我懷疑沒有編譯器優化,它可能會比較慢,因爲在每次迭代時都會創建一個新數組(如果元素不爲零),因爲$0 + [$1!]
。
但很高興知道有很多方法可以達到相同的結果:)
而且*那*是我問的原因。很有用! – 2014-10-27 11:19:58
:) - 閱讀最新的答案更安全的方式做到這一點 – Antonio 2014-10-27 11:23:55
@Antonio你可以刪除這些循環的一個使用'reduce',而不是'filter'和'map'刪除'nil's:'讓整數= array.map {$ 0.toInt()} .reduce([]){$ 1!= nil? $ 0 + [$ 1!]:$ 0}'。你也可以使用'reduce'來完成初始映射,但是你基本上回到'for'循環,我想不出一種方法來做它的單線程。 – 2014-10-27 14:37:28