2015-11-12 29 views
33

残念ながら、私はJQueryやアンダースコアを持たず、純粋なjavascript(IE9互換)を持っていません。JavaScriptのちょうどLINQ SelectMany()に相当する方法

私は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 
+3

それはまったく残念ではありません。純粋なJavaScriptは素晴らしいです。文脈がなければ、あなたがここで達成しようとしていることを理解することは非常に難しいです。 –

+0

@ StoneArcher、答えがどれほど具体的であるかが分かります。可能な回答は多すぎず、最善の答えは短く簡潔でした。 – toddmo

答えて

43

簡単なため:解答へ

おかげで、私はこの作業を得ました。
あなたは数字の配列の配列を考えてみましょう:

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] 
+0

最後のものは 'arr.reduce(function(a、b){return a.concat(b.phoneNumbers);}、[])' – Timwi

4

鷺は、アレイを平らにするためにconcatメソッドを使用して正しいです。しかし、この例に似た何かを得るために、あなたものが

​​

=> [1、2、4、「始めましょう選択部分 https://msdn.microsoft.com/library/bb534336(v=vs.100).aspx

/* arr is something like this from the example PetOwner[] petOwners = 
        { new PetOwner { Name="Higa, Sidney", 
          Pets = new List<string>{ "Scruffy", "Sam" } }, 
         new PetOwner { Name="Ashkenazi, Ronen", 
          Pets = new List<string>{ "Walker", "Sugar" } }, 
         new PetOwner { Name="Price, Vernette", 
          Pets = new List<string>{ "Scratches", "Diesel" } } }; */ 

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

arr.map(property("pets")).reduce(flatten,[]) 
+0

I 'と書かれています。私はあなたのデータをjsonとして使うことができます。コードの1行にあなたの答えを平らにしようとします。 "オブジェクト階層を平坦化する方法の解答方法" lol – toddmo

+0

あなたのデータを自由に使用してください...地図関数を抽象的に抽象化したので、毎回新しい関数を書く必要なく簡単にプロパティ名を選択できます。 '' arr'を '' people''と '' pets''を '' PhoneNumbers''に置き換えてください。 –

+0

私の質問を平坦版で編集し、あなたの答えを投票しました。ありがとう。 – toddmo

3
// you can save this function in a common js file of your project 
function selectMany(f){ 
    return function (acc,b) { 
     return acc.concat(f(b)) 
    } 
} 

var ex1 = [{items:[1,2]},{items:[4,"asda"]}]; 
var ex2 = [[1,2,3],[4,5]] 
var ex3 = [] 
var ex4 = [{nodes:["1","v"]}] 

用のマップが必要になりますASDA "]

ex2.reduce(selectMany(x=>x),[]) 

=> [1、2、3、4、5]

ex3.reduce(selectMany(x=> "this will not be called"),[]) 

=> []

ex4.reduce(selectMany(x=> x.nodes),[]) 

=> [ "1"、 "V"]

注:減らす機能にintitial値として有効な配列(非ヌル)を使用し

しばらく後にそれらのため
1

、JavaScriptを理解することが、まだ活字体で、単純な型付きSelectManyメソッドをしたい:

function selectMany<TIn, TOut>(input: TIn[], selectListFn: (t: TIn) => TOut[]): TOut[] { 
    return input.reduce((out, inx) => { 
    out.push(...selectListFn(inx)); 
    return out; 
    }, new Array<TOut>()); 
} 
関連する問題