在Swift中展平数组数组

Chr*_*ich 124 swift

Swift中是否有flattenScala,Xtend,Groovy,Ruby和co?

var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9] 
Run Code Online (Sandbox Code Playgroud)

当然我可以使用reduce,但那有点糟透了

var flattened = aofa.reduce(Int[]()){
    a,i in var b : Int[] = a
    b.extend(i)
    return b
}
Run Code Online (Sandbox Code Playgroud)

and*_*der 370

Swift 3.0

reduce:

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

flatMap:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = numbers.flatMap { $0 }
Run Code Online (Sandbox Code Playgroud)

joined:

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

  • @Dschee`flatMap`将**或者将2D数组压平成1D数组**或**删除`nil`值,而不是两者.它根据第一级数组的'Element`是一个数组还是可选的来确定要做的事情 - 所以如果你传递一个2D数组的选项_(例如`[[Int?]]`)_它会选择将其展平为1D _(例如`[Int?]`)_.要平坦到1-D并删除第2级nils,你必须做`array.flatMap {$ 0} .flatMap {$ 0}`.换句话说,尺寸展平等于'Array(array.joined())`和nil-removal"flattening"相当于`array.filter {$ 0!= nil} .map {$ 0!}`. (5认同)
  • 为了更一般地说明这一点,`flatMap`从Swift 1.2开始可用. (3认同)
  • `mixed`(正式名称为'flatten`)和`flatMap`之间有什么区别?就是`flatMap`加入时,它也可以映射/转换事物.但是在这个例子中我们真的不需要,即我们返回`$ 0` (2认同)
  • @JimDovey,只是为了澄清一下:flatMap 已“贬值”,这意味着 Apple 不希望您再以任何理由使用它。到了某个时候它就会消失。所以,它可能应该从推荐的答案中删除 (2认同)

Max*_*tov 30

在Swift标准库中,为joined符合Sequence协议的所有类型(或flattenSequenceTypeSwift 3之前)实现了功能,其中包括Array:

let numbers = [[1,2,3],[4],[5,6,7,8,9]]
let flattened = Array(numbers.joined())
Run Code Online (Sandbox Code Playgroud)

在某些情况下,使用joined()可能是有益的,因为它返回一个惰性集合而不是一个新数组,但是在传递给Array()初始化器时总是可以转换为数组,如上例所示.


Raj*_*ari 15

Swift 4.x

只是为了在数组中增加一点复杂性,如果有一个包含数组数组的数组,那么flatMap实际上会失败.

假设数组是

var array:[Any] = [1,2,[[3,4],[5,6,[7]]],8]
Run Code Online (Sandbox Code Playgroud)

什么flatMapcompactMap回报是:

array.compactMap({$0})

//Output
[1, 2, [[3, 4], [5, 6, [7]]], 8]
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,我们可以使用简单的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
}
Run Code Online (Sandbox Code Playgroud)

所以用给定的数组调用这个函数

flattenedArray(array: array)
Run Code Online (Sandbox Code Playgroud)

结果是:

[1, 2, 3, 4, 5, 6, 7, 8]
Run Code Online (Sandbox Code Playgroud)

考虑到Int这里的情况,这个函数将有助于压扁任何类型的数组

游乐场输出: 在此输入图像描述


Nik*_*Loy 12

斯威夫特 4.x

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] 
Run Code Online (Sandbox Code Playgroud)


Rud*_*vič 6

编辑:joined()改为使用:

https://developer.apple.com/documentation/swift/sequence/2431985-joined

原回复:

let numbers = [[1, 2, 3], [4, 5, 6]]
let flattenNumbers = numbers.reduce([], combine: +)
Run Code Online (Sandbox Code Playgroud)


Fra*_*cia 5

斯威夫特 5.1

public extension Array where Element: Collection {

    func flatten() -> [Element.Element] {
        return reduce([], +)
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您还需要它作为字典值:

public extension Dictionary.Values where Value : Collection {
    func flatten() -> [Value.Element]{
         return self.reduce([], +)
    }
}
Run Code Online (Sandbox Code Playgroud)