2012-09-10 12 views
41

कल्पना कीजिए कि मेरे पास घोंसला वाली सरणी संरचना है।LINQ के SelectMany ऑपरेटर के बराबर underscore.js क्या है?

var nested = [ [1], [2], [3] ]; 

underscore.js का उपयोग करते हुए, मैं कैसे एक चपटी सरणी का उत्पादन होगा?

सी # में आप Enumerable.SelectMany इस तरह का प्रयोग करेंगे:

var flattened = nested.SelectMany(item => item); 

नोट इस मामले में लैम्ब्डा नेस्टेड आइटम सीधे चयन करता है, लेकिन यह किसी भी मनमाने ढंग से अभिव्यक्ति हो सकती थी।

jQuery में, यह सिर्फ उपयोग करना संभव है:

var flattened = $.map(nested, function(item) { return item; }); 

हालांकि इस दृष्टिकोण अंडरस्कोर के map समारोह के साथ काम नहीं करता।

तो मैं underscore.js का उपयोग करके flattened array [1, 2, 3] कैसे प्राप्त करूं?

+3

उपयोग _.flatten? – yngccc

+0

आप यह भी लिख सकते हैं: _.map (नेस्टेड, फ़ंक्शन (आइटम) {वापसी आइटम [0];}) – Darragh

+0

@Darragh, जो मेरे विशिष्ट उदाहरण के लिए काम करेगा, लेकिन जब बच्चे के सरणी में कई तत्व होते हैं। –

उत्तर

35
var nested = [ [1], [2], [3] ]; 
var flattened = _.flatten(nested); 

उसके बारे में यहां fiddle

+0

अच्छा और आसान! मैंने उन्हें अपने दस्तावेज़ में क्यों नहीं देखा?:) –

+6

नोटिस: पास उथला = सत्य, यदि आप केवल एक स्तर की फ़्लैटनिंग (जैसे SelectMany करता है) चाहते हैं: '_.flatten (नेस्टेड, सत्य)' –

+2

['flatten'] (https://lodash.com/docs #flatten) डिफ़ॉल्ट रूप से केवल एक स्तर पर प्रतीत होता है; उन्होंने 'flattenDeep' और' flattenDepth' जोड़ा है। – mpen

37

आप एक से थोड़ा अधिक जटिल सरणी है, तो एक JSON से आ रही कहते हैं, आप के रूप में अच्छी pluck विधि का लाभ ले सकते, विशिष्ट संपत्ति आप में रुचि रखते समान हैं निकालने parents.SelectMany(parent => parent.Items); को

// underscore version 
var allitems = _.flatten(_.pluck(parents, 'items')); 

allitems अब माता-पिता, [a,b,c,d] से सभी subitems की सरणी है।

और एक JSFiddle एक ही चीज़ दिखा रहा है।


या, यदि आप उपयोग कर रहे हैं lodash आप _.flatMap समारोह जो टिप्पणी में यह उनका कहना है के लिए संस्करण 4 के बाद से Cred नोएल के लिए उपलब्ध है का उपयोग करके एक ही बात कर सकते हैं।

Array.prototype.selectMany = function(fn) { 
    return Array.prototype.concat(...this.map(fn)); 
}; 

बूम:

var parents = [ 
 
    { name: 'hello', items: ['a', 'b'] }, 
 
    { name: 'world', items: ['c', 'd'] } 
 
]; 
 

 

 
// version 1 of lodash, straight up 
 
var allitems = _.flatMap(parents, 'items'); 
 
logIt('straight', allitems); 
 

 
// or by wrapping the collection first 
 
var allitems = _(parents) 
 
    .flatMap('items') 
 
    .value(); 
 
logIt('wrapped', allitems); 
 

 
// this basically does _(parents).map('items').flatten().value(); 
 

 
function logIt(wat, value) { 
 
    document.getElementById('result').innerHTML += wat + ':' + JSON.stringify(value) + '\r\n<br/>'; 
 
}
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script> 
 
<div id="result"></div>

+1

हालांकि, अंडरस्कोर में लॉनाश के साथ उपलब्ध नहीं है, आप 'flatMap 'का उपयोग करने के लिए' मानचित्र 'और' flatten' का उपयोग करने से सरल बना सकता है, जैसे:' _.flatMap (माता-पिता, "आइटम") ')। – Noel

+0

धन्यवाद @ नोएल, मैं इसे अपने उत्तर में जोड़ दूंगा। उस बारे में नहीं पता था जब मैंने अपना जवाब – Patrick

2

मैं lodash में किसी भी तरीके कि काफी SelectMany तरह काम नहीं मिल सकता है, तो मैं एक का उपयोग कर शुद्ध जे एस बनाया।

> console.log([{a:[1,2],b:'x'},{a:[3,4],b:'y'}].selectMany(o => o.a)); 
[ 1, 2, 3, 4 ] 
+0

वास्तव में लिखा था? मैंने अपने जवाब में एक कामकाजी नमूना शामिल किया है .. उस समाधान के साथ क्या गलत है? – Patrick

+0

@ पैट्रिक संचालन का आदेश। जब घोंसला होता है तो यह भ्रमित हो जाता है: 'a.selectMany (b => b.c.selectMany (d => d.e))'। अपने समाधान का उपयोग करके पुनः लिखने का प्रयास करें। – mpen

3

हम भी कर सकते हैं Patrick's solution एक mixin में इतना है कि यह chainable हो जाता है:

_.mixin({ 
    selectMany: function(collection, iteratee=_.identity) { 
     return _.flatten(_.map(collection, iteratee)); 
    } 
}); 

उदाहरण:

let sample = [{a:[1,2],b:'x'},{a:[3,4],b:'y'}]; 

console.log(_.selectMany(sample, 'a')); // [ 1, 2, 3, 4 ] 
console.log(_.chain(sample).selectMany(o => o.a).filter(a => a % 2 === 0).map(a => a * 3).value()); // [ 6, 12 ] 
संबंधित मुद्दे