在Swift中有没有对应的Scala、Xtend、Groovy、Ruby等等?
var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9]
当然我可以用reduce来做,但那有点糟糕
var flattened = aofa.reduce(Int[]()){
a,i in var b : Int[] = a
b.extend(i)
return b
}
迅速的4.倍和5.倍
为了在数组中增加一点复杂性,如果有一个数组包含数组的数组,那么flatMap实际上会失败。
假设数组是
var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8]
flatMap或compactMap返回的是:
array.compactMap({$0})
//Output
[1, 2, [[3, 4], [5, 6, [7]]], 8]
为了解决这个问题,我们可以使用简单的for循环逻辑+递归
func flattenedArray(array:[Any]) -> [Int] {
var myArray = [Int]()
for element in array {
if let element = element as? Int {
myArray.append(element)
}
if let element = element as? [Any] {
let result = flattenedArray(array: element)
for i in result {
myArray.append(i)
}
}
}
return myArray
}
用给定的数组调用这个函数
flattenedArray(array: array)
结果是:
[1, 2, 3, 4, 5, 6, 7, 8]
考虑到这里Int的情况,这个函数将有助于将任何类型的数组平化
操场上的输出:
快4.倍
flatMap的这种用法并没有被弃用,它就是为此而生的。
https://developer.apple.com/documentation/swift/sequence/2905332-flatmap
var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatMap { $0 } //[1,2,3,4,5,6,7,8,9]
reduce的另一个更通用的实现,
let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let reduced = reduce(numbers,[],+)
这完成了同样的事情,但可能会对reduce中发生的事情有更多的了解。
从苹果公司的文件来看,
func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U
描述
返回反复调用combine的结果,并依次返回初始化为initial的累积值和sequence的每个元素。
你可以用下面的方法来平嵌套数组:
var arrays = [1, 2, 3, 4, 5, [12, 22, 32], [[1, 2, 3], 1, 3, 4, [[[777, 888, 8999]]]]] as [Any]
func flatten(_ array: [Any]) -> [Any] {
return array.reduce([Any]()) { result, current in
switch current {
case(let arrayOfAny as [Any]):
return result + flatten(arrayOfAny)
default:
return result + [current]
}
}
}
let result = flatten(arrays)
print(result)
/// [1, 2, 3, 4, 5, 12, 22, 32, 1, 2, 3, 1, 3, 4, 777, 888, 8999]