【JS】vol. 2/3 データ検索(Underscore.jsライブラリの便利なメソッド)〜Chapter4 ブレイクスルーJavaScript フロントエンジニアとして越えるべき5つの壁〜
Underscore.jsとは
配列を扱う上で役立つライブラリ。
JavaScriptは多言語に比べて配列操作に弱いので補完してくれる。
プロトタイプ汚染もなく、map,filter,invoke,bindAllなど便利な関数が100以上用意されている。
mapメソッド
引数として与えられた関数を書く配列要素に対して実行し、
その結果から新しい配列を生成する。
例:複数のオブジェクトが入った配列の中から、あるkeyのvalueを集めたい場合に便利。
var stooges = [ { name:"curly", age:25 },{ name:"moe", age:21 },{ name:"larry", age:23 } ]; _.map(stooges, function(e){ return e.name; });
結果
["curly", "moe", "larry"]
filterメソッド
引数で与えられた関数を各配列要素に対して実行し、合格したものだけを抽出した新しい配列を生成する。
n以上またはn以下のものを抽出したい場合に便利。
_.filter([12,5,8,130,44], function(e){ return e >= 10; });
結果[12,130,44]
reduceメソッド
引数で与えられた関数を書く配列要素に対して(左から右へ)実行。
その際に直前の配列要素で処理した返り値を受け取る。
配列の全ての和を求めたい時に便利。
_.reduce([0,1,2,3] , function(prev, current) { return prev + current; });
結果
6
invokeメソッド
配列の各要素に対して、引数に指定した関数名を実行する。
sortしたいだけなど、目的がはっきりしている時に便利。
_.invoke([5,1,7], ["Carol","Alice", "Bob"]], "sort");
結果
[[1,5,7],["Alice","Bob","Carol"]]
bindAllメソッド
オブジェクトを関数にバインドする。
関数が呼ばれた時にthisが参照する値をobjectの値にすることができる。
例:clickイベントを登録する時、thisの参照する値をobjectにする
var buttonView = { label:"underscore", onClick:function(){ alert("clicked: " + this.label); }, onHover:function(){ console.log("hovering: " + this.label); } }; _.bindAll(buttonView, "onClick","onHover"); $("#underscore_button").on("click", buttonView.onClick);
結果
clicked: underscore
データ検索を実装する
function App(url) { this.bindEvents(); var self = this; this.fetch(url).then(function(data) { self.data = data; }, function(e) { console.error("データの取得に失敗しました"); }); } App.prototype.bindEvents = function() { _.bindAll(this, "onChange"); $("select").on("change", this.onChange); }; App.prototype.fetch = function(url) { return $.ajax({ url: url, dataType: "json" }); }; App.prototype.onChange = function(e) { var self = this; var where = $("select").map(function(i, el) { var $el = $(el); return function(list) { return self[$el.attr("name")](list, $el.val()); }; }); var list = _.reduce(where, function(prev, current) { return current(prev); }, this.data.list); }; App.prototype.sort = function(list, key) { if (this.isEmpty(key)) { return list; } return _.sortBy(list, function(e) { return e[key]; }); }; App.prototype.filter = function(list, value) { if (this.isEmpty(value)) { return list; } return _.filter(list, function(e) { return e["group"] === value; }); }; App.prototype.isEmpty = function(value) { return value === ""; }; new App("data.json");
※onChangeとは、フォーム内のエレメント(要素)の内容が変更された時に起こるイベント処理の事