altJSであるTypeScriptと関数型でのプログラミングをサポートするUnderscore.jsを使い、関数型プログラミングについての理解を深めていくために、様々な問題を解いていく記事を定期的に記載していきたいと思います。
TypeScriptについて簡単に知りたい方はこちらを参照してください。
公式ページ
Welcome to TypeScript
参考になる記事
TypeScriptで学ぶJavaScript入門:第1回 TypeScriptの概要 (1/4) - @IT
Underscore.jsについて簡単に知りたい方はこちらを参照してください。
公式ページ
Underscore.js
参考になる記事
Underscore.jsの入り口:連載|gihyo.jp … 技術評論社
さて、第1回はワードカウント問題を解いていきたいと思います。
※ワードカウント問題などの例は下記のかとうじゅんいちさんの問題例から拝借させていただきました。
https://gist.github.com/j5ik2o/7210762
私は下記のように解いてみました。
ここからはコードの解説をしていきたいと思います。
- 1行目
下記のコードでUnderscore.jsを読み込んでいます。
/// <reference path='typings/tsd.d.ts' />
TypeScriptでJavaScriptのライブラリを読み込む際にはHTMLでライブラリ自身を読み込む他に、別途方定義ファイルを読み込むことが必要となります。
型定義ファイルについて、詳しくはこちら。
TypeScriptの型定義ファイルを共有しよう! - Qiita
JavaScript - WebStorm で TypeScript を始めよう!《Advent Calendar 2014》 - Qiita
TypeScriptの型定義ファイル(d.ts)をTSDを用いて管理する。 | Developers.IO
- 4行目
ここでは関数定義をしていますが、ここではTypeScriptのアロー関数式を使用しています。
ここのアロー関数式では{}を使わない記法を用いているため、関数定義ですがreturnを書く必要がありません。
値を返すことを前提としている関数型っぽい書き方を実現できるわけです。
var countFruitsFromLines = (list:string[]) =>
アロー関数式については下記を参考にしてください。
Playground - Welcome to TypeScript
- 5行目
ここではUnderscore.jsを使用し、chainメソッドを使用しています。
Underscore.jsは_.メソッド名という形で使用します。
chainメソッドは、チェーン記法で連続処理を行うメソッドです。
チェーン内のそれぞれの関数はchainメソッドの引数で渡されたオブジェクトを処理した結果をラッパーオブジェクトに格納して、チェーン上の次のメソッドに渡します。
チェーン内のメソッドにはラッパーオブジェクトが渡され、メソッドの1つ目のパラメータは省略されます。
__.chain(list:string[])
chainメソッドについて、説明がわかりにくかった場合は下記の記事を参考にしてください。
第3回 underscore.jsの関数とユーティリティとChaining:Underscore.jsの入り口|gihyo.jp … 技術評論社
- 7行目
ここでは、mapメソッドを使い、mapメソッドの引数にmapメソッドで実行されるメソッドの定義をアロー関数式で記述しています。
mapメソッドは、第1引数で渡される配列/オブジェクトのそれぞれの要素に対して、第2引数で定義された関数に渡して、実行した結果を配列で返します。
また、第1引数がオブジェクト型であっても戻り値は配列となります。
そして、今回はchainメソッドにより、mapメソッドに渡される第1引数は省略されています。
splitメソッドは、JavaScipt自体のメソッドで、引数で渡された文字列を区切り文字とし、レシーバの文字列を配列にして返すものです。
.map((_list:string[]) => _list.split(' '))
mapメソッドについて、説明がわかりにくかった場合は下記の記事を参考にしてください。
第2回 Underscore.jsのコレクションと配列とオブジェクトの機能:Underscore.jsの入り口|gihyo.jp … 技術評論社
- 9行目
ここでは、flattenメソッドを使い、ネストされている配列に関して、ネストを解いて平坦な新しい配列にして返しています。
.flatten()
flattenメソッドについて、説明がわかりにくかった場合は下記の記事を参考にしてください。
第3回 underscore.jsの関数とユーティリティとChaining:Underscore.jsの入り口|gihyo.jp … 技術評論社
- 11行目
ここでは、配列の要素をカウントし、それぞれの要素とその出現回数をキー値として格納したオブジェクトを返します。
.countBy()
この関数の存在を知る前には下記のようなコードを記述していました。
.reduce(function (counts, word) { counts[word] = (counts[word] || 0) + 1; return counts; }, {})
ちなみにreduce関数は第1引数に渡された配列/オブジェクトに関して、それぞれの要素を左から順番に第2引数で定義された関数に渡して実行し、その結果を結合することで単一の値まで煮詰めると言ったようなものです。
すごく簡単に言えば、再帰関数をこの関数で置き換えできるようなイメージです。
reduceの引数で定義している関数については、JavaScriptでよく使うイディオムを使用していますので初めて見た方は調べてみてください。
reduceメソッドについて、説明がわかりにくかった場合は下記の記事を参考にしてください。
第2回 Underscore.jsのコレクションと配列とオブジェクトの機能:Underscore.jsの入り口|gihyo.jp … 技術評論社
- 13行目
このvalueメソッドは、chainメソッドの最後に記述するもので、ラッパーオブジェクトからchainメソッドの処理結果を抽出して返します。
.value();
いかがでしたでしょうか。
関数型がまだあまりよくわかっていなくてコードを記述しているので、もっと良いやり方があるなど突っ込み等ありましたら、コメントしてくださると嬉しいです。
- 作者: Michael Fogus,和田祐一郎
- 出版社/メーカー: オライリージャパン
- 発売日: 2014/01/18
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (5件) を見る
関数プログラミング実践入門 ──簡潔で、正しいコードを書くために (WEB+DB PRESS plus)
- 作者: 大川徳之
- 出版社/メーカー: 技術評論社
- 発売日: 2014/11/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (3件) を見る
- 作者: Richard bird,山下伸夫
- 出版社/メーカー: オーム社
- 発売日: 2014/11/12
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
- 作者: わかめまさひろ,井上章,丸山弘詩
- 出版社/メーカー: インプレスジャパン
- 発売日: 2014/05/16
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
大規模開発でも小規模開発でも使える TypeScript実践入門
- 作者: 川俣晶
- 出版社/メーカー: 技術評論社
- 発売日: 2014/09/12
- メディア: 大型本
- この商品を含むブログ (3件) を見る
TypeScript実践プログラミング (Programmer's SELECTION)
- 作者: スティーブ・フェントン,鈴木幸敏,株式会社クイープ
- 出版社/メーカー: 翔泳社
- 発売日: 2015/01/23
- メディア: 大型本
- この商品を含むブログを見る