2015-11-12 8 views
33

दुर्भाग्यवश, मेरे पास JQuery या Underscore नहीं है, केवल शुद्ध जावास्क्रिप्ट (IE9 संगत) है।LINQ SelectMany() के बराबर कैसे करें जावास्क्रिप्ट

मैं LINQ कार्यक्षमता से SelectMany() के बराबर चाहता हूं।

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

क्या मैं कर सकता हूं?

संपादित करें: चयन आप सरणी के समारोह को कम उपयोग कर सकते हैं

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

यह दुर्भाग्यपूर्ण नहीं है। शुद्ध जावास्क्रिप्ट अद्भुत है। संदर्भ के बिना, यह समझना बहुत मुश्किल है कि आप यहां क्या हासिल करने की कोशिश कर रहे हैं। –

+0

@ स्टर्लिंगआर्चर, देखें कि उत्तर कितना विशिष्ट है। बहुत सारे संभावित उत्तर नहीं थे और सबसे अच्छा जवाब छोटा और संक्षिप्त था। – 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) {a aconcon (b.phoneNumbers);}, []) ' – Timwi

4

Sagi concat विधि का उपयोग कर एक सरणी समतल में सही है। लेकिन इस उदाहरण की तरह कुछ पाने के लिए, आप भी एक नक्शे के चयन भाग के लिए 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

मैं एक पहेली बनाने जा रहा हूं; मैं आपके डेटा का उपयोग जेसन के रूप में कर सकता हूं। कोड के एक पंक्ति में अपने उत्तर को फ़्लैट करने का प्रयास करेंगे। "ऑब्जेक्ट पदानुक्रमों को फ़्लैट करने के बारे में एक जवाब कैसे फ़्लैट करें" lol – toddmo

+0

अपने डेटा का उपयोग करने के लिए स्वतंत्र महसूस करें ... मैंने स्पष्ट रूप से नक्शा फ़ंक्शन को सारणीबद्ध किया ताकि आप प्रत्येक बार एक नया फ़ंक्शन लिखने के बिना आसानी से किसी भी संपत्ति का नाम चुन सकें। ''फोन' के साथ 'एआर'' और' "पालतू जानवर" के साथ 'एआर'' को प्रतिस्थापित करें ' –

+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"]}] 

के शुरू करते हैं की आवश्यकता होगी

ex1.reduce(selectMany(x=>x.items),[]) 

=> [1, 2, 4, " एस्डा "]

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", "वी"]

नोट: को कम समारोह में intitial मूल्य के रूप में मान्य सरणी (गैर नल) का उपयोग

1

उन लोगों के लिए थोड़ी देर के बाद, जावास्क्रिप्ट को समझने, लेकिन अभी भी टाइपप्रति में एक साधारण Typed 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>()); 
} 
संबंधित मुद्दे