2014-10-27 112 views
0

我正在读取包含键/值行到Swift结构中的文本文件。文件的其中一行在行中有五个空格分隔的值,我使用componentsSeparatedByString转换为数组。将字符串数组复制到一个整数数组?

的实际值是整数,所以正常的解决办法是遍历每一个,并将其复制到我的结构的int数组中相关联的槽。但是我在这里错过了一些Swift(或基础)魔法?

回答

2

可以使用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!]

但很高兴知道有很多方法可以达到相同的结果:)

+0

而且*那*是我问的原因。很有用! – 2014-10-27 11:19:58

+0

:) - 阅读最新的答案更安全的方式做到这一点 – Antonio 2014-10-27 11:23:55

+0

@Antonio你可以删除这些循环的一个使用'reduce',而不是'filter'和'map'删除'nil's:'让整数= array.map {$ 0.toInt()} .reduce([]){$ 1!= nil? $ 0 + [$ 1!]:$ 0}'。你也可以使用'reduce'来完成初始映射,但是你基本上回到'for'循环,我想不出一种方法来做它的单线程。 – 2014-10-27 14:37:28

相关问题