readLine()をシーケンスのように扱う

Swiftでコンソールアプリを作るときの、標準入力から得た文字列をコレクションのように扱う方法です。

標準入力を扱う処理をシンプルに書く場合、readLine()関数と繰り返しを使って次のようにすることが多いです。

while let line = readLine() {
    // 入力された行に対する処理
}

ループを回して、行単位で得られた値をループ内で処理する、という方法です。よく見ます。

これはこれで必要十分なのですが、これをもっとコレクションのようにして、たとえばmap()flatMap()と組み合わせて使いたいと思いました。

// 以下はイメージ
readLinesIterator().filter{ … }.map{ … }

なにかいい方法はないものかと調べていたら、いつものStackOverflowにこんな回答を見つけました。

stackoverflow.com

リンク先はswiftのバージョンが古いので、今風に書き直してみます。

AnyIterator{ readLine() }.filter{ … }.map{ … }

readLine()AnyIteratorでラップしてあげるだけというお手軽さです。 これで処理を宣言的にも書けるようになり、とても便利な世界が待っています。