web-dev-qa-db-ja.com

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($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
}

これはただ明白な悪いです。これは迅速ではないという本能があります。

上記の方法よりも迅速に配列をフラット化するにはどうすればよいですか?ワンライナーがいいでしょう。

14
Sweeper

これには 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 }
_
25
jtbandes

Swift 5)を使用すると、配列をフラット化するために、次の3つの方法のいずれかを選択できます。


#1。 ArrayflatMap(_:)メソッドを使用して配列をフラット化します

Swiftでは、Sequenceプロトコル(Arrayを含む)に準拠する型にはflatMap(_:)メソッドがあります。 Array's flatMap(_:) には次の宣言があります。

_func flatMap<SegmentOfResult>(_ transform: (Element) throws -> SegmentOfResult) rethrows -> [SegmentOfResult.Element] where SegmentOfResult : 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。 Arrayjoined()メソッドを使用して配列をフラット化します

Arrayにはjoined()というメソッドがあります。 joined() には次の宣言があります。

_func joined() -> FlattenSequence<Array<Element>>
_

このシーケンスシーケンスの要素を連結して返します。

次の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。 Arrayreduce(_:_:)メソッドを使用して配列をフラット化します

Swift Arrayには reduce(_:_:) メソッドがあり、次の宣言があります。

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

指定されたクロージャを使用してシーケンスの要素を組み合わせた結果を返します。

次の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]
_
6
Imanou Petit