JavaScript
lodash

もうlodashなんていらないなんて言わないよ絶対: iteratee編

Lodash/Underscoreは必要ない(かも) - Qiita

「lodashいらんやん、jsネイティブで同じの使えるやん」と言われて久しいですが、やっぱりlodash便利です。

たとえばmap

var users = [
  {
    name: 'Alice',
    age: 18,
    sex: 'female'
  },
  {
    name: 'Bob',
    age: 23,
    sex: 'male'
  },
  {
    name: 'Charlie',
    age: 54,
    sex: 'male'
  }
];

このような配列があります。ここからnameだけを取り出した配列を作るにはどうすればいいでしょうか。

// js native
users.map(function(user) {
  return user.name;
});

// lodash
_.map(users, 'name')

lodashでももちろんjsと同じ書き方ができますが、本来functionを渡すべき引数にstringを渡すと_.propertyが呼ばれます。

// _.property Example
var objects = [
  { 'a': { 'b': 2 } },
  { 'a': { 'b': 1 } }
];

_.map(objects, _.property('a.b'));
// => [2, 1]

_.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
// => [1, 2]

その結果このようなショートハンドが使えます。便利。

続いて今度はfilterを使ってsex==='male'のobjectを抽出してみましょう。

// js native
users.filter(function(user) {
  return user.sex === 'male';
});

// lodash with object
_.filter(users, {sex: 'male'});
// lodash with array
_.filter(users, ['sex', 'male']);

もちろんjsネイティブのfunctionを渡す方法はlodashでもできますが、関数じゃなくObjectを渡すと_.matchesが呼ばれます。

// _.matches Example
var objects = [
  { 'a': 1, 'b': 2, 'c': 3 },
  { 'a': 4, 'b': 5, 'c': 6 }
];

_.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
// => [{ 'a': 4, 'b': 5, 'c': 6 }]

Arrayだと_.matchesPropertyが呼ばれます。

// _.matchesProperty Example
var objects = [
  { 'a': 1, 'b': 2, 'c': 3 },
  { 'a': 4, 'b': 5, 'c': 6 }
];

_.find(objects, _.matchesProperty('a', 4));
// => { 'a': 4, 'b': 5, 'c': 6 }

引数の型によってそれぞれに振り分けているのが_.iterateeです。

// _.iteratee Example
var users = [
  { 'user': 'barney', 'age': 36, 'active': true },
  { 'user': 'fred',   'age': 40, 'active': false }
];

// これは `_.matches` のショートハンドだよ!
_.filter(users, _.iteratee({ 'user': 'barney', 'active': true }));
// => [{ 'user': 'barney', 'age': 36, 'active': true }]

// これは `_.matchesProperty` のショートハンドだよ!
_.filter(users, _.iteratee(['user', 'fred']));
// => [{ 'user': 'fred', 'age': 40 }]

// これは `_.property` のショートハンドだよ!
_.map(users, _.iteratee('user'));
// => ['barney', 'fred']

この関数は関数を返します。

1. 関数を渡したらそのままの関数を返します
2. Objectを渡すと_.matchesを返します
3. Arrayを渡すと_.matchesPropertyを返します
4. それ以外だと_.propertyを返します

lodashの配列操作メソッドの多くはこの_.iterateeを実装しています。

mapだろうがcountByだろうがsomeだろうがfindだろうがfindIndexだろうが、とても多くのメソッドで使えます。

さらに自分自身で配列操作の関数を書く時に使えば上の機能を簡単に実装できます。

もちろんlodashは配列操作や反復処理だけじゃないのでまだまだ魅力は尽きないのですが、このiterateeというメソッドだけでも便利すぎて歌いたくなります。

もうlodashなんていらないなんて言わないよ絶対

続く(かも)