1. ホーム
  2. javascript

[解決済み] LINQのSelectMany()と同等の機能をjavascriptで実現する方法

2022-09-28 20:45:45

質問

残念ながら、JQueryやUnderscoreは持っておらず、純粋なjavascript(IE9対応)だけです。

私はLINQの機能からSelectMany()に相当するものが欲しいのです。

// SelectMany flattens it to just a list of phone numbers.
IEnumerable<PhoneNumber> phoneNumbers = people.SelectMany(p => p.PhoneNumbers);

できるかな?

EDITです。

回答のおかげで、これが動くようになりました。

var petOwners = 
[
    {
        Name: "Higa, Sidney", Pets: ["Scruffy", "Sam"]
    },
    {
        Name: "Ashkenazi, Ronen", Pets: ["Walker", "Sugar"]
    },
    {
        Name: "Price, Vernette", Pets: ["Scratches", "Diesel"]
    },
];

function property(key){return function(x){return x[key];}}
function flatten(a,b){return a.concat(b);}

var allPets = petOwners.map(property("Pets")).reduce(flatten,[]);

console.log(petOwners[0].Pets[0]);
console.log(allPets.length); // 6

var allPets2 = petOwners.map(function(p){ return p.Pets; }).reduce(function(a, b){ return a.concat(b); },[]); // all in one line

console.log(allPets2.length); // 6

どのように解決するのですか?

単純な選択であれば、Arrayのreduce関数を使用することができます。

例えば、数値の配列の配列があるとします。

var arr = [[1,2],[3, 4]];
arr.reduce(function(a, b){ return a.concat(b); }, []);
=>  [1,2,3,4]

var arr = [{ name: "name1", phoneNumbers : [5551111, 5552222]},{ name: "name2",phoneNumbers : [5553333] }];
arr.map(function(p){ return p.phoneNumbers; })
   .reduce(function(a, b){ return a.concat(b); }, [])
=>  [5551111, 5552222, 5553333]

編集します。

es6 からは、Array プロトタイプに flatMap が追加されました。 SelectMany と同義です。 flatMap .

このメソッドはまずマッピング関数を用いて各要素をマッピングし、その結果を新しい配列にフラット化します。 TypeScriptでの簡略化されたシグネチャは以下の通りです。

function flatMap<A, B>(f: (value: A) => B[]): B[]

このタスクを達成するためには、各要素をphoneNumbersにflatMapする必要があるだけです。

arr.flatMap(a => a.phoneNumbers);