Enumerable.Linq の各メソッドを JavaScript ではどう書くか?（メソッドの対応）

#はじめに
内容は随時補完されます！
.NET の [Linq](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable) に慣れ親しんでいる方向けに、[JavaScript](https://developer.mozilla.org/ja/docs/Web/JavaScript)での似たメソッドへの対応を一覧化したものです。

Linq でいう「シーケンス」を、Javascript でいう「索引付きコレクション（配列など、インデックス値で順序付けされたデータのコレクション）」「配列風オブジェクト[^a]」「キー付きコレクション（反復可能オブジェクト[^b]）」のすべて、またはいずれかとほぼ同じとみなして対応させています。

#一覧
まったく同じ機能とは限らないので注意です。（元となる配列自体を書き換える(*マークつき)、メソッドチェーンにならない、同値判定・False判定法が違うなど）

|Linq|JavaScript|JSでの機能|
|:---|:---|:---|
|[Aggregate](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.aggregate)|[reduce](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)<br><br>[reduceRight](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight)|配列の各要素に対してreducer関数を実行して単一の値を返す<br><br>配列の各要素に対して右から左へreducer関数を実行して単一の値を返す|
|[All](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.all)|[every](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/every)|配列のすべての要素が、与えられた関数によって実行されるテストに通るかテストする|
|[Any](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.any)|[some](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/some)|配列の少なくとも1つの要素が、渡された関数によって実施されるテストに通るかテストする|
|[Append](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.append)|*[push](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/push)<br><br>[concat]()|配列自体の末尾に1つ以上の要素を追加する<br><br>配列に他の配列や値をつないだ新しい配列を返す|
|[Average](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.average)|reduce で代用など||
|[Cast](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.cast)|map で代用など||
|[Concat](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.concat)|[concat](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/concat)|配列に他の配列や値をつないだ新しい配列を返す。2以上の配列や値も一度に指定可能|
|[Contains](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.contains)|[includes](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)|配列に特定の要素が含まれているかを返す|
|[Count](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.count)|[length](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function/length)||
|[Distinct](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.distinct)|[Set](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set) オブジェクト生成など||
|[Empty](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.empty)|[[ ]](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array)||
|[First](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.first)|[find](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find)|配列内の、提供されたテスト関数を満たす最初の要素の値を返す。配列すべての要素にテスト関数が呼び出されるので注意。|
|[FirstOrDefault](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.firstordefault)|↑||
|[Last](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.last)|sort と find で代用など||
|[LastOrDefault](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.lastordefault)|↑||
|[Max](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.max)|[Math.max](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/max)<br><br>reduce で代用など|引数として与えた複数の数の中で最大の数を返す|
|[Min](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.min)|[Math.min](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/max)<br><br>reduce で代用など|引数として与えた複数の数の中で最小の数を返す|
|[OrderBy](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.orderby)|*[sort](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)|配列自体の要素をソートする|
|[OrderByDescending](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.orderbydescending)|↑||
|[Prepend](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.prepend)|*[splice](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)|配列自体の既存の要素を取り除いたり、置き換えたり、新しい要素を追加したりする|
|[Reverse](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.reverse)|*[reverse](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse)|配列自体の要素を反転させて返す|
|[Select](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.select)|[map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)|配列のすべての要素に対して与えられた関数を実行し、その結果からなる新しい配列を生成して返す|
|[SelectMany](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.selectmany)|[flat](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)<br/><br/>[flatMap](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)|すべてのサブ配列の要素を指定した深さで再帰的に結合した新しい配列を生成して返す<br><br>マッピング関数を使用してそれぞれの要素をマップした後、結果を新しい配列内にフラット化して返す|
|[Skip](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.skip)|*[splice](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)|配列自体の既存の要素を取り除いたり、置き換えたり、新しい要素を追加したりする|
|[SkipLast](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.skiplast)|*[splice](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)|配列自体の既存の要素を取り除いたり、置き換えたり、新しい要素を追加したりする|
|[SkipWhile](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.skipwhile)|filter で代用など||
|[Sum](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.sum)|redure　で代用など||
|[Take](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.take)|[subarray](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray)<br><br>[slice](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)|指定される範囲から同じ要素の型をもつ新しい配列を生成して返す<br><br>配列の一部をシャローコピーして新しい配列オブジェクトを返す|
|[TakeLast](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.takelast)|↑||
|[TakeWhile](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.takewhile)|filter で代用など||
|[ToArray](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.toarray)|[from](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from)|「配列風オブジェクト[^a]」や「反復可能オブジェクト[^b]」から新しい浅いコピーのArrayインスタンスを生成して返す|
|[Where](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.where)|[filter](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)|各配列要素に対して、与えられたテスト関数を実行し、合格したすべての配列要素からなる新しい配列を生成して返す|

<!---


|[AsEnumerable](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.asenumerable)|||

|[DefaultIfEmpty](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.defaultifempty)|||

|[ElementAt](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.elementat)|||
|[ElementAtOrDefault](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.elementatordefault)|||

|[Except](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.except)|||

|[GroupBy](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.groupby)|||
|[GroupJoin](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.groupjoin)|||
|[Intersect](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.intersect)|||
|[Join](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.join)|||

|[LongCount](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.longcount)|||

|[OfType](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.oftype)|||

|[Range](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.range)|||
|[Repeat](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.repeat)|||

|[SequenceEqual](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.sequenceequal)|||
|[Single](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.single)|||
|[SingleOrDefault](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.singleordefault)|||


|[ThenBy](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.thenby)|||
|[ThenByDescending](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.thenbydescending)|||


|[ToDictionary](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.todictionary)|||
|[ToHashSet](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.tohashset)|||
|[ToList](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.tolist)|||
|[ToLookup](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.tolookup)|||
|[Union](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.union)|||

|[Zip](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.zip)|||

####################

[of](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/of)
[copyWithin](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin)
[entries](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/entries)
[fill](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/fill)
[findIndex](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex) - IList.IndexOf
[forEach](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
[indexOf](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
[join](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/join)
[key](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/keys)
[lastIndexOf](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
[pop](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/pop)
[shift](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/shift)
[slice]
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice)
[splice](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/splice)
[toLocaleString](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/toLocaleString)
[toSource](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/toSource)
[unshift](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift)
[values](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/values)
[set](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/set)

-->

[^a]: 配列風オブジェクト (length プロパティおよびインデックス付けされた要素を持つオブジェクト （[Array.from](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from) - MDN より）

[^b]: [Map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Map) や [Set](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set) のような要素を取得するオブジェクト（[Array.from](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/from) - MDN より）

#対応例
##[Select](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq.enumerable.select) - [map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) （配列添字情報つき）
```c#:C#
var req = new[] { 160, -2, 0, 5 };
var res = req.Select((s, i) => s * i);
// -> { 0, -2 , 0, 15 }
```

```javascript:JavaScript
let req = [16, -2, 0, 5];
var res = req.map(function(s, i) { return s * i; });
// -> [ 0, -2, 0, 15 ]
```


#補足
##linq.js
便利なライブラリがあるようです。

- [JavaScriptで配列をLINQにより処理できるライブラリ「linq.js」を利用するには？](https://www.atmarkit.co.jp/fdotnet/dotnettips/1058linqjsbasic/linqjsbasic.html) - @
ITさん

##ジェネレーター関数
.NET でいう IEnumerable&lt;T&gt;を戻り型とする関数と似た概念があり、[function*](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/function*)と記載することで、[yield](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/yield) (C# の [yield return](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/yield)) や [yield*](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/yield*) を使用できます。

```javascript:JavaScript
function* OneTwoThree(s) {
    yield "1" + s;
    yield "2" + s;
    yield "3" + s;
}

for (let v of OneTwoThree("個")) { console.log(v); }
for (let v of OneTwoThree("本")) { console.log(v); }
// ->
// 1個
// 2個
// 3個
// 1本
// 2本
// 3本
```

#さいごに
間違いのご指摘、便利な書き方、ぜひぜひお寄せ下さいませ！

#参考情報 ありがとうございます！
- [JavaScript 屋さんのための C# LINQ 入門](https://mseeeen.msen.jp/linq-basic-for-javascript-programmers-2/)
- [MDN Javascript リファレンス](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference)
- [MSDN Docs .NET APIブラウザー](https://docs.microsoft.com/ja-jp/dotnet/api/)