Edited at

lodash の forEach/map/reduce 系の関数を紹介

JavaScript を使っているなら lodash は大変便利なのですが、関数が多すぎてどれ使ったらいいのか解りづらいのが難点です。

ここではその中でも良く使う、配列ループ系の関数群を整理して紹介します。


forEach 系


  • 配列/オブジェクトをループして処理する。


  • return falsebreak


  • forEach: JS標準の forEach と違ってオブジェクトでも使える。 length プロパティがあったら配列と判断。forEachRight は逆順。


  • forIn: オブジェクト専用 forEach 。length の影響受けない。親クラスのプロパティも対象。forInRight は逆順。


  • forOwn: オブジェクト専用 forEach 。length の影響受けない。親クラスのプロパティは対象外。forInRight は逆順。

_.forEach([1, 2], function(value) {

console.log(value);
});
// => `1` → `2` の順に表示

_.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
console.log(key);
});
// => `a` → `b` の順に表示 (とはいえ順番は保証されない)


Map 系


  • 配列/オブジェクトをループして 要素を減らさずに 値やキーを変更した新しい配列/オブジェクトを作る。


  • map: JS標準の map と違ってオブジェクトでも使える。 配列 を返す。


map

_.map({ 'a': 4, 'b': 8 }, n => n * n); // => [16, 64] (順序は保証されない)

// _.propertyのショートハンドが使える
var users = [{user: 'barney'}, {user: 'fred'}];
_.map(users, 'user'); // => ['barney', 'fred']
_.map(users, _.property('user')); // 同じ意味
_.map(users, u => u.user); // 同じ意味




  • mapKeys: オブジェクトのキーを変更する。オブジェクト を返す。


  • mapValues: オブジェクトの値を変更する。オブジェクト を返す。

_.mapKeys({ 'a': 1, 'b': 2 }, (value, key) => key + value); // => { 'a1': 1, 'b2': 2 }

_.mapValues({ 'a': 1, 'b': 2 }, (value, key) => key + value); // => { 'a': 'a1', 'b': 'b2' }

// id をキーにハッシュマップを作るのにも使えます。
_.mapKeys([{id: 1}, {id: 2}], v => v.id); // => { 1: {id: 1}, 2: {id: 2} }



  • invokeMap: 第2引数で指定したものを関数として実行した結果で差し替える。配列 を返す。


invokeMap

_.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); // => [[1, 5, 7], [1, 2, 3]]

_.invokeMap([123, 456], String.prototype.split, ''); // => [['1', '2', '3'], ['4', '5', '6']]


reduce/transform 系


  • 配列/オブジェクトをループして新しい値(accumulator)を作る。


  • reduce では accumulator を戻り値で返す。なので accumulator に数値や boolean も使える。


  • transform では accumulator を関数の中で書き換える。なので accumulator に使えるのは配列とオブジェクトのみ。戻り値はループを中断したい場合に使う。


  • reduceRight はループが逆順に回る。


合計を作る場合

_.reduce([1, 2], (sum, n) => sum + n, 0); // => 3



各要素を二乗した新たな配列を作るが、二乗した値が奇数になったらそれ以降の値は切り捨てる場合

_.transform([2, 3, 4], function(result, n) {

result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]


値とキーを逆転させる。逆転後、同一キーの値がありえるので、値は配列にする場合


// reduce で実現
_.reduce({ 'a': 1, 'b': 2, 'c': 1 }, (result, value, key) => {
(result[value] || (result[value] = [])).push(key);
return result;
}, {});
// => { '1': ['a', 'c'], '2': ['b'] }

// reduce で実現
_.transform({ 'a': 1, 'b': 2, 'c': 1 }, (result, value, key) => {
(result[value] || (result[value] = [])).push(key);
}, {});
// => { '1': ['a', 'c'], '2': ['b'] }

// ちなみにこの要件なら invertBy 使ったほうが簡単
_.invertBy({ 'a': 1, 'b': 2, 'c': 1 })
// => { '1': ['a', 'c'], '2': ['b'] }



lodash関連の記事