在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
}

当前回答

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的每个元素。

其他回答

迅速的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.2

我在下面写了一个简单的数组扩展。可用于将包含另一个数组或元素的数组平展。不像joined()方法。

public extension Array {
    public func flatten() -> [Element] {
        return Array.flatten(0, self)
    }

    public static func flatten<Element>(_ index: Int, _ toFlat: [Element]) -> [Element] {
        guard index < toFlat.count else { return [] }

        var flatten: [Element] = []

        if let itemArr = toFlat[index] as? [Element] {
            flatten = flatten + itemArr.flatten()
        } else {
            flatten.append(toFlat[index])
        }

        return flatten + Array.flatten(index + 1, toFlat)
    }
}

用法:

let numbers: [Any] = [1, [2, "3"], 4, ["5", 6, 7], "8", [9, 10]]

numbers.flatten()

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的每个元素。

Swift >= 3.0

减少:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let reduced = numbers.reduce([], +)

flatMap:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = numbers.flatMap { $0 }

加入:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let joined = Array(numbers.joined())

修改了@RahmiBozdag的回答, 1. 公共扩展中的方法是公共的。 2. 删除了额外的方法,因为开始索引将始终为零。 3.我没有找到一种方法把compactMap内部为nil和可选的,因为内部方法T总是[Any?],欢迎提出任何建议。

 let array = [[[1, 2, 3], 4], 5, [6, [9], 10], 11, nil] as [Any?]

 public extension Array {

 func flatten<T>(_ index: Int = 0) -> [T] {
        guard index < self.count else { 
            return [] 
        }

        var flatten: [T] = []

        if let itemArr = self[index] as? [T] {
            flatten += itemArr.flatten()
        } else if let element = self[index] as? T {
            flatten.append(element)
        }
        return flatten + self.flatten(index + 1)
   }

}

let result: [Any] = array.flatten().compactMap { $0 }
print(result)
//[1, 2, 3, 4, 5, 6, 9, 10, 11]