41
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-07-15

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'] }
 
// transform で実現
_.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関連の記事

41
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?