让我说我有一个字符串数组,我想将它映射到一个Int数组我可以使用map函数:
var arrayOfStrings: Array = ["0", "a"]
let numbersOptional = arrayOfStrings.map { $0.toInt() }
// numbersOptional = "[Optional(0), nil]"
Run Code Online (Sandbox Code Playgroud)
Numbers现在是一个Int?数组,但我想要一个Int数组.我知道我可以这样做:
let numbers = arrayOfStrings.map { $0.toInt() }.filter { $0 != nil }.map { $0! }
// numbers = [0]
Run Code Online (Sandbox Code Playgroud)
但这似乎并不是很迅速.从Int数组转换?对于Array of Int,需要使用相当多的样板函数来调用filter和map.有更快捷的方法吗?
更新:从Swift 1.2开始,有一个内置的flatMap数组方法,但它不接受Optionals,所以下面的帮助程序仍然有用.
我喜欢使用辅助flatMap函数来处理这类事情,就像Scala flatMap对集合的方法一样(可以将Scala Option视为0或1元素的集合,粗略地说):
func flatMap<C : CollectionType, T>(source: C, transform: (C.Generator.Element) -> T?) -> [T] {
var buffer = [T]()
for elem in source {
if let mappedElem = transform(elem) {
buffer.append(mappedElem)
}
}
return buffer
}
let a = ["0", "a", "42"]
let b0 = map(a, { $0.toInt() }) // [Int?] - [{Some 0}, nil, {Some 42}]
let b1 = flatMap(a, { $0.toInt() }) // [Int] - [0, 42]
Run Code Online (Sandbox Code Playgroud)
flatMap对于Optional更一般的flatMap应该做的事情,这个定义是一个特殊情况:
func flatMap<C : CollectionType, T : CollectionType>(source: C, transform: (C.Generator.Element) -> T) -> [T.Generator.Element] {
var buffer = [T.Generator.Element]()
for elem in source {
buffer.extend(transform(elem))
}
return buffer
}
Run Code Online (Sandbox Code Playgroud)
我们得到的地方
let b2 = flatMap(a, { [$0, $0, $0] }) // [String] - ["0", "0", "0", "a", "a", "a", "42", "42", "42"]
Run Code Online (Sandbox Code Playgroud)
使用reduce来建立新的数组可能是更地道
func filterInt(a: Array<String>) -> Array<Int> {
return a.reduce(Array<Int>()) {
var a = $0
if let x = $1.toInt() {
a.append(x)
}
return a
}
}
Run Code Online (Sandbox Code Playgroud)
例
filterInt(["0", "a", "42"]) // [0, 42]
Run Code Online (Sandbox Code Playgroud)
你真正想要的是一个collect(map+ filter)方法.鉴于您需要应用特定的过滤器,在这种情况下甚至flatMap可以工作(参见Jean-Philippe的回答).太糟糕了,swift标准库没有提供这两种方法.
更新:Xcode 7.2 \xe2\x80\xa2 Swift 2.1.1
\n\nlet arrayOfStrings = ["0", "a", "1"]\nlet numbersOnly = arrayOfStrings.flatMap { Int($0) }\n\nprint(numbersOnly) // [0,1]\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
2672 次 |
| 最近记录: |