2012-09-10 7 views
41

私はネストされた配列構造を持っているとします。LINQのSelectMany演算子に相当するアンダースコア.jsとは何ですか?

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

underscore.jsを使用すると、どのように平坦化配列が生成されますか?この場合、ラムダは直接ネストされたアイテムを選択したが、それは任意の式だったかもしれないことを

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

注:C#ので

あなたは、このようEnumerable.SelectManyを使用します。 jQueryので

、それだけで使用することが可能です:

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

このアプローチは、アンダースコアのmap機能では動作しませんが。

フラット化された配列[1, 2, 3]はどのようにしてunderscore.jsを使用しますか?類似したあなたはもう少し複雑な配列を持っている場合は、1がJSONから来ると言う、はあなたが興味のある特定のプロパティを抽出し、同様pluck方法を利用することができます

+3

使用_.flattenを? – yngccc

+0

また、私の具体的な例では動作するが、子配列に複数の要素が含まれている場合は動作しない_Map(入れ子、関数(項目){戻り項目[0];}) – Darragh

+0

@Darraghと書くこともできます。 –

答えて

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

相続人fiddle

+0

素敵で簡単!なぜ私はそれらの文書でそれを見なかったのですか?:) –

+6

Notice:SelectManyと同様に、フラット化のレベルを1つだけにしたい場合は、shallow = trueを渡します。 '_.flatten(nested、true)' –

+2

['flatten'](https://lodash.com/docs) #flatten)はデフォルトでは1つのレベルのみを実行するように見えます。彼らは 'flattenDeep'と' flattenDepth'を追加しました。 – mpen

37

parents.SelectMany(parent => parent.Items);

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

allitemsに今の親からのすべてのサブ項目、[a,b,c,d]の配列です。

と同じものを示すJSFiddleです。


それとも、あなたが使用している場合lodashあなたはコメントでそれを指摘してノエルへのバージョン4.クレド以降で使用可能です_.flatMap機能を使って、同じことを行うことができます。

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

アンダースコアでは使用できませんが、 'map'と' flatten'を 'flatMap'だけを使って、' _.flatMap(parents、 "items") ')のように単純化することができます。 – Noel

+0

ありがとうございます@ノエル、私はそれを私の答えに追加します。私は私の答えを書いたときにそのことについて知らなかった – Patrick

2

私はかなりSelectManyのように動作lodashのいずれかの方法を見つけることができませんでしたので、私は純粋なJS使って1を作成しました:

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

ブームを。

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

本当に?私は私の答えに働いているサンプルを含んでいます。その解決策に何が問題なのですか? – Patrick

+0

@Patrick操作の順序。 'a.selectMany(b => b.c.selectMany(d => d.e))'のように入れ子になると混乱します。ソリューションを使って書き直してみてください。 – mpen

3

それはチェーン可能となるように、我々はまた、ミックスインにPatrick's solutionを行うことができます。

_.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 ] 
関連する問題