Swift 4.1flatMap
は非推奨のようです。ただし、Swift 4.1compactMap
には新しいメソッドがあり、同じことをしていますか? flatMap
を使用すると、コレクション内の各オブジェクトを変換し、nilであったアイテムを削除できます。
flatMapと同様
let array = ["1", "2", nil]
array.flatMap { $0 } // will return "1", "2"
compactMapと同様
let array = ["1", "2", nil]
array.compactMap { $0 } // will return "1", "2"
compactMap
は同じことをしています。
これら2つの方法の違いは何ですか?なぜAppleメソッドの名前を変更することに決めたのですか?
flatMap
には3つの異なるバリアントがあります。 Optional値を返すクロージャを受け入れるSequence.flatMap(_:)
のバリアントは非推奨になりました。 SequenceとOptionalの両方でのflatMap(_:)
の他のバリアントはそのままです。提案文書で説明されている理由は、誤用のためです。
廃止されたflatMap
バリアント機能は、新しいメソッドcompactMap
でまったく同じです。
詳細を参照してください こちら 。
Swift標準ライブラリはflatMap
関数の3つのオーバーロードを定義します:
Sequence.flatMap<S>(_: (Element) -> S) -> [S.Element]
Optional.flatMap<U>(_: (Wrapped) -> U?) -> U?
Sequence.flatMap<U>(_: (Element) -> U?) -> [U]
最後のオーバーロード関数は、2つの方法で誤用される可能性があります。
次の構造体と配列を検討してください。
struct Person {
var age: Int
var name: String
}
let people = [Person(age: 21, name: "Osame"), Person(age: 17, name: "Masoud"), Person(age: 20, name: "Mehdi")]
最初の方法:追加のラッピングとアンラッピング:people
配列に含まれる人物の年齢の配列を取得する必要がある場合、次の2つの関数を使用できます。
let flatMappedAges = people.flatMap({$0.age}) // prints: [21, 17, 20]
let mappedAges = people.map({$0.age}) // prints: [21, 17, 20]
この場合、map
関数がジョブを実行し、両方が同じ結果を生成するため、flatMap
を使用する必要はありません。さらに、このflatMapのユースケースには、無用のラッピングおよびアンラッピングプロセスがあります(クロージャーパラメーターは、返される値をOptionalでラップし、flatMapの実装は、返される前にOptional値をアンラップします)
2番目の方法-収集プロトコルへの文字列適合:people
配列から人物の名前のリストを取得する必要があると考えてください。次の行を使用できます。
let names = people.flatMap({$0.name})
Swift 4.0より前のバージョンを使用していた場合、変換されたリストが得られます
["Osame", "Masoud", "Mehdi"]
しかし、新しいバージョンではString
はCollection
プロトコルに準拠しているため、flatMap()
を使用すると、3番目の関数ではなく最初のオーバーロード関数と一致し、変換後のフラットな結果が得られます値:
["O", "s", "a", "m", "e", "M", "a", "s", "o", "u", "d", "M", "e", "h", "d", "i"]
結論:flatMap()の3番目のオーバーロードは廃止されました
これらの誤用のため、SwiftチームはflatMap関数への3番目のオーバーロードを廃止することを決定しました。そして、Optional
sに対処する必要がある場合のソリューションこれまでのところ、compactMap()
と呼ばれる新しい関数を導入することで、期待される結果が得られます。