athome-developer’s blog

不動産情報サービスのアットホームの開発者が発信するブログ

LodashとLINQの対応表

こんにちは! 情報システム部の高野です。
前回、Lodashについて書きましたがその続きです。

Lodashを使ってるとLINQと同様の処理が名前違いで存在するので
サーバー処理とクライアント処理を行ったり来たり書いているとよく、あれ?
ってなることがあります。*1
(じゃ~linq.jsを使えばいいじゃないって意見はそっと棚の上に置いておくことにします)


ということで備忘録的に対応表を作っておこうじゃないかと。
(私がよく使う関数限定ですけど)

LINQ Lodash
射影 Select map
フィルター Where filter
昇順ソート OrderBy orderBy
降順ソート OrderByDescending orderBy
グループ化 GroupBy groupBy
存在確認 Any some
最初の要素取得 First find
最後の要素取得 Last findLast
一意の要素取得 Distinct uniq
和集合 Union union
差集合 Except difference
積集合 Intersect intersection
平坦化 SelectMany flatten
スキップ Skip drop
指定数要素取得 Take take
合計計算 Sum sum*2
最大値取得 Max max*3
最小値取得 Min min*4

名前だけ上げておくだけだとイマイチなので特徴的なものをいくつか掘り下げてみます。

使い方

まずは、この関数達をどのように使うのかって話なんですけど


LINQ

var result = src.Where(x => x.Name == "Hoge");


Lodash*5

var result = _(src).filter(x => x.name === "Hoge");

このように基本的にはLINQでもLodashでもほぼ同じような書き方になります。
一部、全然書き方が異なったり他の関数と混同しそうなものがあるのでご紹介します。

ソート

ソートは、LINQとLodashで大きく異なります。


LINQの場合は、昇順と降順で異なる関数を使うことになります。

var asc = src.OrderBy(x => x.Id);
var desc = src.OrderByDescending(x => x.Id);


そして結構はまるポイントなのが、複数キーによるソートです。

var result = src.OrderByDescending(x => x.Name).ThenBy(x => x.Id);

ThenByが正しいのですが、OrderByを重ねてもエラーにはならないので慣れてない人は間違うことが多いです。


一方、Lodash

var result = _(src).orderBy(["name", "id"], ["desc", "asc"]);

1つの関数で昇順・降順も書けますし複数ソートキーも1つの関数で書くことができます。
(文字列での指定なのがちょっと気になるところではありますが)

存在確認

コレクションの中身が存在するかどうかの確認を行うのが
LINQだとAny、Lodashだとsomeになります。
こちらは両方とも条件指定しなければコレクションが空かどうか判断できますし
条件を指定すればその条件に合致するものがあるかどうか判断できます。
Lodashには、これとは別にincludesという関数があります。


someの場合は、条件を式で渡すことができます。

var result = _(src).some(x => x.name === "Hoge"); // Hogeという名前があればtrue


includesの場合は、単純でその値があるかどうかだけを判定します。

var result = _([1,2,3]).includes(2); // この場合はtrue
最初の要素取得

最初の要素を取得するのは、LINQだとFirstかFirstOrDefaultです。
こちらは名前的には分かりやすいのですが
Lodashはfindになります。ちょっと分かりづらいですね。
これらは両方とも条件指定がなければコレクションの最初の要素を取得します。
条件指定すればその条件に合致する最初の要素を取得します。

その他にLodashには、headという関数があり
これがLINQのFirstと同じ動きをするように思えるのですが
こちらは、条件指定ができません。

var result = _([1,2,3]).head(); // この場合は1

紛らわしい……。

ページング

所謂、ページングを行う時に使う関数でLINQではSkipとTakeを使います。
Skipでシーケンスを読み飛ばしTakeで必要数だけ要素を取り出します。
これをLodashでやるには、dropとtakeを使うと同じように書けます。

_([0,1,2,3,4,5,6,7,8,9]).drop(2).take(5).forEach(x => console.log(x));
//  2 3 4 5 6

Skipとdropが同じとは思えなかったので探すのが大変でした。

まとめ

このような感じでLINQとLodashは、同じ名前の関数もあれば
全然違う名前で同じ処理をするものがあります。
また同じ処理を実行する関数でも指定方法が違ったりします。
LINQの関数名はSQLに影響されているものが多く
どちらかと言うとLINQの方が異端なのかもしれませんね。

*1:よく考えればJavaScript標準の集合関数も同じことが言えますね

*2:公式サイトのドキュメントだとMathというカテゴリになっているので注意

*3:sum同様

*4:sum同様

*5:ES5以前のJavaScriptだと書き方が異なります。ES2015かTypeScriptでお試しください。