あっ、はい、ちょっとタイトル大げさでしたね・・・
しかも今更感満載ですが・・・
ちまたではかなり人気みたいですが、なんでか最近まで知りませんでした。
もっと早くに知っていたら色々楽だったんだろうな〜〜と思えるライブラリです。
ちょっとしたことを便利にしてくれる便利屋さんです。
今日は、このライブラリの中でも特にこれがあって良かった!ってのを2つピックアップして紹介します。
でも普通の紹介じゃなくて、「どんなケースで役に立ったか」を主体に書いてみたいと思います。
ケース1
テスト結果のデータがあります。
そのデータはこんな感じ。
A君・・・55点
B君・・・41点
C君・・・79点
D君・・・13点
E君・・・83点
これを点数の範囲でクラス分けしたい、とします。
クラスは以下の4つ(名前と条件)。
rank1・・・75点以上
rank2・・・50点以上75点未満
rank3・・・25点以上50点未満
rank4・・・25点未満
プログラム的に書くと、
こういうデータを
[
{ name: 'A君', score: 55 },
{ name: 'B君', score: 41 },
{ name: 'C君', score: 79 },
{ name: 'D君', score: 13 },
{ name: 'E君', score: 83 }
];
こうしたい
{
rank1: [
{ name: 'C君', score: 79 },
{ name: 'E君', score: 83 }
],
rank2: [
{ name: 'A君', score: 55 }
],
rank3: [
{ name: 'B君', score: 41 }
],
rank4: [
{ name: 'D君', score: 13 }
]
};
わけです。
これを自力で書くとすると・・・
(例)
var data = [
{ name: 'A君', score: 55 },
{ name: 'B君', score: 41 },
{ name: 'C君', score: 79 },
{ name: 'D君', score: 13 },
{ name: 'E君', score: 83 }
];
var result = {};
for (var i in data) {
var key = 'rank4';
if (data[i].score >= 75) {
key = 'rank1';
} else if (data[i].score >= 50 && data[i].score < 75) {
key = 'rank2';
} else if (data[i].score >= 25 && data[i].score < 50) {
key = 'rank3';
}
if (!(key in result)) {
result[key] = [];
}
result[key].push(data[i]);
}
console.log(result);
/*
結果 =>
{
rank1: [
{ name: 'C君', score: 79 },
{ name: 'E君', score: 83 }
],
rank2: [
{ name: 'A君', score: 55 }
],
rank3: [
{ name: 'B君', score: 41 }
],
rank4: [
{ name: 'D君', score: 13 }
]
}
*/
こんな感じになるんやと思うんですが、underscoreを使うと
var data = [
{ name: 'A君', score: 55 },
{ name: 'B君', score: 41 },
{ name: 'C君', score: 79 },
{ name: 'D君', score: 13 },
{ name: 'E君', score: 83 }
];
var result = _(data).groupBy(function(val) {
if (val.score >= 75) {
return 'rank1';
} else if (val.score >= 50 && val.score < 75) {
return 'rank2';
} else if (val.score >= 25 && val.score < 50) {
return 'rank3';
} else {
return 'rank4';
}
});
console.log(result);
/*
結果 =>
{
rank1: [
{ name: 'C君', score: 79 },
{ name: 'E君', score: 83 }
],
rank2: [
{ name: 'A君', score: 55 }
],
rank3: [
{ name: 'B君', score: 41 }
],
rank4: [
{ name: 'D君', score: 13 }
]
}
*/
みたいになります。
引数にグループのkeyを返す関数を渡してあげるだけ。
外側に一旦変数を宣言する必要がないのと、keyがあるかないかのチェックが無くなりました。
underscoreのgroupBy
という関数を使うとこれが出来ます。
些細な事なんでしょうけど、こういうのの積み重ねはたくさんの量を書かないといけないときに相当気分が楽になります。
コード量的にもケアレスミス防げますしね。
ケース2
ケース1のようなデータ
[
{ name: 'A君', score: 55 },
{ name: 'B君', score: 41 },
{ name: 'C君', score: 79 },
{ name: 'D君', score: 13 },
{ name: 'E君', score: 83 }
];
を、nameとかscoreとかのkeyを無くして、
{
'A君': 55,
'B君': 41,
'C君': 79,
'D君': 13,
'E君': 83
};
といった感じで、名前: スコア
みたいなオブジェクトにしたい(なんか日本語入っててプロパティ名的にどうなの、といったことは今は考えないようにしてます)、といった場合とかは
var data = [
{ name: 'A君', score: 55 },
{ name: 'B君', score: 41 },
{ name: 'C君', score: 79 },
{ name: 'D君', score: 13 },
{ name: 'E君', score: 83 }
];
var result = _(data).chain().map(function(val) {
return [ val.name, val.score ];
}).object().value();
console.log(result);
/*
{
'A君': 55,
'B君': 41,
'C君': 79,
'D君': 13,
'E君': 83
}
*/
みたいに書けます。
ここでは、map
, object
という関数を使っています。
mapは配列を新しい形の配列にすることができます。
そこで[ 名前, スコア ]
という2つの要素を持った配列を返すことで、配列の配列(2次元配列)を作っています。
その後、object関数で配列の各要素をkey: value
の形で変換してます。
個人的に一番気に入った点
上記ケース2でchainという関数と、valueという関数を使っています。
これを使うと関数を次々実行することが出来ます。
chainによって一つ一つの関数がunderscoreのオブジェクト(ラップされたオブジェクト)を返すようになるためです。
けれど、最後そのままやとunderscoreのオブジェクトのままなので、値として取り出すのにvalueを呼びます。
こういう関数のチェーンは関数型の言語やと結構あったりすると思うんですが、やっぱりできるのとできないのでは全然違います。
省略できるものは省略したいので。
今回は2ケース紹介しましたけど、Underscoreのドキュメントをサーっと眺めているだけでも、「こんな時使えるな」みたいなのが思い浮かんでくると思います。
(サンプルが分り易いので)
コレクション、配列、オブジェクトの操作系が多いですが、それ以外の機能もあります。
人気なのが分かる気がします・・・
以上、簡単ですがライブラリ紹介記事でした。