如何在 Swift 中快速展开数组?
How can I flatten an array swiftily in Swift?
我想转这个:
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([=13=]) }
但这会使生成的数组可变,这是不必要的。我不喜欢这样。
我尝试使用 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
}
这 很糟糕 。我有一种直觉,这并不迅速。
如何比上述方法更快地展平数组?一条线就好了。
有一个名为 joined
的内置函数:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].joined()
(请注意,这实际上并不是 return 另一个数组,它 return 是一个 FlattenSequence
,但这通常无关紧要,因为它仍然是您可以使用的序列使用 for
循环等等。如果你真的很在意,你可以使用 Array(arrayOfArrays.joined())
。)
flatMap
function也能帮到你。它的签名大致是
flatMap<S: SequenceType>(fn: (Generator.Element) -> S) -> [S.Generator.Element]
这意味着您可以传递一个 fn
,对于任何元素 return 都是一个序列,它会 combine/concatenate 这些序列。
由于数组的元素本身就是序列,因此您可以使用仅 return 元素本身的函数({ x in return x }
或等同于 {[=20=]}
):
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].flatMap{ [=12=] }
数组中的展平函数:
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({[=11=]})
print(y)
你的输出:
使用Swift5,您可以选择以下三种方式之一来展平数组。
#1。使用 Array
的 flatMap(_:)
方法
展平数组
使用Swift,符合Sequence
协议(包括Array
)的类型有一个flatMap(_:)
方法。 Array
的 flatMap(_:)
具有以下声明:
func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.
下面的 Playground 示例代码显示了如何使用 flatMap(_:)
:
将类型 [[Int]]
的 Array
展平为类型 [Int]
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。使用 Array
的 joined()
方法
展平数组
Array
有一个名为 joined()
的方法。 joined()
有以下声明:
func joined() -> FlattenSequence<Array<Element>>
Returns the elements of this sequence of sequences, concatenated.
以下 Playground 示例代码显示了如何使用 joined()
将类型 [[Int]]
的 Array
展平为类型 [Int]
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenCollection = array.joined()
let flattenArray = Array(flattenCollection)
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
#3。使用 Array
的 reduce(_:_:)
方法
展平数组
Swift Array
有一个 reduce(_:_:)
方法,声明如下:
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
Returns the result of combining the elements of the sequence using the given closure.
以下 Playground 示例代码显示了如何使用 reduce(_:_:)
将类型 [[Int]]
的 Array
展平为类型 [Int]
:
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]
作为 reduce(_:_:)
的替代方法,您可以使用 reduce(into:_:)
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce(into: [Int]()) { (result: inout [Int], element: [Int]) in
result += element
}
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
你只需要使用2个函数就可以做到
已加入()
compactMap
让 y = x.compactMap{$0}.joined().compactMap{$0}
我想转这个:
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([=13=]) }
但这会使生成的数组可变,这是不必要的。我不喜欢这样。
我尝试使用 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
}
这 很糟糕 。我有一种直觉,这并不迅速。
如何比上述方法更快地展平数组?一条线就好了。
有一个名为 joined
的内置函数:
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].joined()
(请注意,这实际上并不是 return 另一个数组,它 return 是一个 FlattenSequence
,但这通常无关紧要,因为它仍然是您可以使用的序列使用 for
循环等等。如果你真的很在意,你可以使用 Array(arrayOfArrays.joined())
。)
flatMap
function也能帮到你。它的签名大致是
flatMap<S: SequenceType>(fn: (Generator.Element) -> S) -> [S.Generator.Element]
这意味着您可以传递一个 fn
,对于任何元素 return 都是一个序列,它会 combine/concatenate 这些序列。
由于数组的元素本身就是序列,因此您可以使用仅 return 元素本身的函数({ x in return x }
或等同于 {[=20=]}
):
[[1, 2, 3], [4, 5, 6], [7, 8, 9]].flatMap{ [=12=] }
数组中的展平函数:
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({[=11=]})
print(y)
你的输出:
使用Swift5,您可以选择以下三种方式之一来展平数组。
#1。使用 Array
的 flatMap(_:)
方法
展平数组
使用Swift,符合Sequence
协议(包括Array
)的类型有一个flatMap(_:)
方法。 Array
的 flatMap(_:)
具有以下声明:
func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : Sequence
Returns an array containing the concatenated results of calling the given transformation with each element of this sequence.
下面的 Playground 示例代码显示了如何使用 flatMap(_:)
:
[[Int]]
的 Array
展平为类型 [Int]
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。使用 Array
的 joined()
方法
展平数组
Array
有一个名为 joined()
的方法。 joined()
有以下声明:
func joined() -> FlattenSequence<Array<Element>>
Returns the elements of this sequence of sequences, concatenated.
以下 Playground 示例代码显示了如何使用 joined()
将类型 [[Int]]
的 Array
展平为类型 [Int]
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenCollection = array.joined()
let flattenArray = Array(flattenCollection)
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
#3。使用 Array
的 reduce(_:_:)
方法
展平数组
Swift Array
有一个 reduce(_:_:)
方法,声明如下:
func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, Element) throws -> Result) rethrows -> Result
Returns the result of combining the elements of the sequence using the given closure.
以下 Playground 示例代码显示了如何使用 reduce(_:_:)
将类型 [[Int]]
的 Array
展平为类型 [Int]
:
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]
作为 reduce(_:_:)
的替代方法,您可以使用 reduce(into:_:)
:
let array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
let flattenArray = array.reduce(into: [Int]()) { (result: inout [Int], element: [Int]) in
result += element
}
print(flattenArray) // prints [1, 2, 3, 4, 5, 6, 7, 8, 9]
你只需要使用2个函数就可以做到
已加入()
compactMap
让 y = x.compactMap{$0}.joined().compactMap{$0}