web-dev-qa-db-ja.com

LINQのSelectMany演算子に相当するunderscore.jsは何ですか?

ネストされた配列構造があると想像してください。

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

nderscore.js を使用して、フラット化された配列をどのように作成しますか?

C#では Enumerable.SelectMany このように:

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

この場合のラムダはネストされたアイテムを直接選択しますが、任意の式である可能性があることに注意してください。

JQueryでは、次のように使用することができます。

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

ただし、このアプローチはアンダースコアの map 関数では機能しません。

だから私はどのようにフラット化された配列を取得します[1, 2, 3] underscore.jsを使用していますか?

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

ヘレス フィドル

40
armen.shimoon

JSONからのものなど、もう少し複雑な配列がある場合は、 pluck メソッドを利用して、parents.SelectMany(parent => parent.Items);のように、興味のある特定のプロパティを抽出できます。

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

allitemsは、親のすべてのサブアイテムの配列[a,b,c,d]になりました。

そして JSFiddle は同じことを示しています。


または、lodashを使用している場合は、バージョン4以降で使用できる _。flatMap 関数を使用して同じことを行うことができます。コメントで指摘するためにNoelに信用してください。

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) {
  console.log(wat, value)
}
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
<pre id="result"></pre>

より多くのことをしたいが演算子をチェーンしたくない場合は、 flow 関数を使用して同じ効果を得ることができます。これは、TypeScriptを使用して各演算子を個別にインポートする場合に役立ちます。最終的なペイロードを最適化できるためです。

const parents = [
  { name: 'hello', items: ['a', 'b'] },
  { name: 'world', items: ['c', 'd'] }
];
logIt('original', parents);

const result = _.flow(
  (collection) => _.flatMap(collection, (item) => item.items),
  (flattened) => flattened.filter((item) => item !== 'd')
)(parents);
logIt('result without "d"', result);

function logIt(wat, value) {
  console.log(wat, value);
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<pre id="result"></pre>
41
Patrick

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 ]
3
mpen

LodashでSelectManyのように機能するメソッドを見つけることができなかったため、純粋なJSを使用してメソッドを作成しました。

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 ]
2
mpen