如何在Swift中快速展平数组?

时间:2016-05-14 00:32:48

标签: arrays swift flatten

我想转此:

let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

进入这个:

[1, 2, 3, 4, 5, 6, 7, 8, 9]
非常优雅。

当然,最直接的方式是

var y = [Int]()
x.forEach { y.appendContentsOf($0) }

但是这会使得结果数组变得可变,这是不必要的。我不喜欢这样。

我尝试使用reduce

let y = x.reduce([Int]()) { (array, ints) -> [Int] in
    array.appendContentsOf(ints)
    return array
}

但是编译器抱怨array是不可变的,所以我不能调用变异方法appendContentsOf

因此,我添加了一些内容:

let y = x.reduce([Int]()) { (array, ints) -> [Int] in
    var newArr = array
    newArr.appendContentsOf(ints)
    return newArr
}

这只是普通的错误。我有一种本能,这不是很好。

如何比上述方法更加平滑地展平阵列?单线会很好。

4 个答案:

答案 0 :(得分:23)

这个名为joined的内置函数:

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

(注意,这实际上不会返回另一个数组,它会返回FlattenBidirectionalCollection,但这通常无关紧要,因为它仍然是一个可以与for循环和诸如此类使用的序列。如果您真的在意,可以使用Array(arrayOfArrays.joined())。)

flatMap function也可以帮到你。它的签名大致是

flatMap<S: SequenceType>(fn: (Generator.Element) -> S) -> [S.Generator.Element]

这意味着你可以传递一个fn,它可以为任何元素返回一个序列,并且它会组合/连接这些序列。

由于数组的元素本身是序列,因此您可以使用仅返回元素本身的函数({ x in return x }或等效{$0}):

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

答案 1 :(得分:5)

使用Swift 3,根据您的需求和品味,您可以选择以下三种方式之一来展平阵列。

1。使用Sequence flatMap(_:)方法

展平数组

Swift为符合flatMap(_:)协议(包括Sequence)的所有类型提供Array方法。 flatMap(_:)具有以下declaration

func flatMap<SegmentOfResult : Sequence>(_ transform: (Self.Iterator.Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Iterator.Element]
  

返回一个数组,其中包含使用此序列的每个元素调用给定转换的连接结果。

以下操场代码显示了如何使用Array方法展开[[Int]]类型[Int]flatMap(_:)类型:

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.flatMap({ (element: [Int]) -> [Int] in
    return element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

2。使用Sequence joined()方法和Array init(_:)初始值设定项

展平数组

Swift还为符合joined()协议(包括Sequence)的所有类型提供Array方法。 joined()具有以下declaration

func joined() -> FlattenSequence<Self>
  

返回序列序列的元素。

此外,Swift Array有一个init(_:)初始化程序。 init(_:)具有以下declaration

init<S : Sequence where S.Iterator.Element == Element>(_ s: S)
  

创建一个包含序列元素的数组。

因此,以下Playground代码展示了如何使用Array方法和[[Int]]初始化程序将[Int]类型joined()展平为init(_:)

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenCollection = array.joined() // type: FlattenBidirectionalCollection<[Array<Int>]>
let flattenArray = Array(flattenCollection)
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

3。使用Array reduce(_:_:)方法

展平数组

Swift Arrayreduce(_:_:)方法。 reduce(_:_:)具有以下declaration

func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
  

返回使用此序列的每个元素和累积值调用给定组合闭包的结果。

以下操场代码显示了如何使用Array方法展开[[Int]]类型[Int]reduce(_:_:)类型:

let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce([], { (result: [Int], element: [Int]) -> [Int] in
    return result + element
})
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]

答案 2 :(得分:1)

你只需要使用 2 个函数来做到这一点

  1. 加入()

  2. 紧凑型地图

    让 y = x.compactMap{$0}.joined().compactMap{$0}

Reference for more about FlattenSequence

答案 3 :(得分:-1)

数组中的展平功能

let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let y = Array(x.flatten())
print(y)
数组中的

flatMap函数:

let x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let y = x.flatMap({$0})
print(y)

您的输出:

enter image description here

更多信息:Array in Swift