Menu
Coddy logo textTech

パイプラインの構築

CoddyのSwiftジャーニー「ロジックとフロー」セクションの一部 — レッスン 31/56。

これまでに学んだメソッド、mapfilterreducecompactMapflatMapsorted(by:)は、Swiftにおける日常的なツールキットです。実際のコードでは、これらを組み合わせて使用します。

struct Order {
    let item: String
    let qty: Int
}
let orders = [Order(item: "apple", qty: 3), Order(item: "bread", qty: 0), Order(item: "milk", qty: 5)]
let names = orders
    .filter { $0.qty > 0 }
    .sorted { $0.qty > $1.qty }
    .map { $0.item }
print(names)                  // ["milk", "apple"]

チェーンを上から下に読みます。空ではない注文を保持し、数量の降順で並べ替え、名前のみを抽出します。

パイプラインは、各ステップが1つの目的を持っているときに真価を発揮します。もしクロージャの中で2つのことを同時に行っている(マッピングフィルタリングなど)ことに気づいたら、それらを2つのステップに分割しましょう。そうすることで、チェーンが長くなっても可読性が保たれます。

challenge icon

チャレンジ

中級

1行の入力を読み込みます。これは name:price:qty 形式のエントリをカンマで区切ったリストです。一部のエントリは形式が正しくないため、スキップする必要があります。価格(price)または数量(qty)が有効な整数でないエントリはすべてスキップしてください。

qty > 0 である 有効な エントリごとに1行を出力するパイプラインを構築します。合計(price * qty)の 降順 でソートし、以下の形式で出力してください:

<name>: <total>

各アイテムの行の後に、総計を示すサマリー行を1行 Sum: <n> の形式で出力してください。

入力が apple:3:2,bread:bad:1,milk:4:5,cheese:8:0,salt:2:7 の場合、出力は以下のようになります:

milk: 20
salt: 14
apple: 6
Sum: 40

チートシート

高階関数を連結(チェイン)させることで、各ステップが1つの目的を持つ、可読性の高いパイプラインを作成できます。

let names = orders
    .filter { $0.qty > 0 }
    .sorted { $0.qty > $1.qty }
    .map { $0.item }

一般的なパイプラインメソッド:filtercompactMapsorted(by:)mapreduce。もしクロージャが一度に2つのこと(例:マッピングフィルタリング)を行っている場合は、2つのステップに分割してください。

自分で試してみよう

let entries = readLine()!.components(separatedBy: ",")

// TODO: compactMap (解析)、filter (数量 > 0)、
// sorted (合計の降順)、map (フォーマット) を使用したパイプライン。各行と合計を出力。
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

ロジックとフローのすべてのレッスン