sorted(by:)
CoddyのSwiftジャーニー「ロジックとフロー」セクションの一部 — レッスン 30/56。
数値や文字列のような Comparable な値の配列に対して .sorted() を使用したことがあるでしょう。それ以外の基準でソートしたい場合は、2つの要素を受け取り、最初の要素が2番目の要素の前に来るべきときに true を返すクロージャを渡します。
let words = ["banana", "hi", "hello"]
let byLength = words.sorted { $0.count < $1.count }
print(byLength) // ["hi", "hello", "banana"]降順にするには、比較を入れ替えます:
let down = words.sorted { $0.count > $1.count }
print(down) // ["banana", "hello", "hi"]クロージャは、派生した値、長さ、最後の文字、ハッシュ内のエントリなど、あらゆる値を比較できます。クロージャが何を比較するかによって、ソート順が決まります。
min(by:) と max(by:) も同様に動作しますが、ソートされたコピーではなく、単一のオプショナルな要素を返します。
チャレンジ
中級1行の入力を読み込みます。これはカンマで区切られた name:age のペアのリストです。
以下の3行を出力してください:
- 年齢の昇順でソートされた名前を
,で連結したもの。年齢が同じ場合は、名前のアルファベット順でソートしてください。 - 最高齢の人の名前(
max(by:)を使用してください)。同年齢の場合は、最初に出現した人が優先されます。 - 最年少の人の名前(
min(by:)を使用してください)。同年齢の場合は、最初に出現した人が優先されます。
入力が alice:30,bob:22,cara:30,dan:18 の場合、出力は以下のようになります:
dan,bob,alice,cara
alice
danチートシート
任意の派生値でソートするには、カスタムクロージャを指定して .sorted { } を使用します。このクロージャは2つの要素を受け取り、最初の要素が2番目の要素の前に来るべき場合に true を返します:
let words = ["banana", "hi", "hello"]
let byLength = words.sorted { $0.count < $1.count }
// ["hi", "hello", "banana"]降順にするには、演算子を入れ替えます:
let down = words.sorted { $0.count > $1.count }
// ["banana", "hello", "hi"]min(by:) と max(by:) は同じクロージャシグネチャを使用しますが、単一のオプショナル要素を返します:
let longest = words.max(by: { $0.count < $1.count }) // "banana"
let shortest = words.min(by: { $0.count < $1.count }) // "hi"自分で試してみよう
let people = readLine()!.components(separatedBy: ",").map { pair -> (String, Int) in
let parts = pair.components(separatedBy: ":")
return (parts[0], Int(parts[1])!)
}
// TODO: 年齢の昇順でソート(同点の場合は名前でソート)。最年長には max(by:)、最年少には min(by:) を使用。
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。