什么是underscore.js相当于LINQ的SelectMany运算符?

Dre*_*kes 46 javascript linq underscore.js

想象一下,我有一个嵌套的数组结构.

var nested = [ [1], [2], [3] ];
Run Code Online (Sandbox Code Playgroud)

使用underscore.js,我将如何生成扁平数组?

在C#中你会这样使用Enumerable.SelectMany:

var flattened = nested.SelectMany(item => item);
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,lambda直接选择嵌套项,但它可以是任意表达式.

在jQuery中,可以使用:

var flattened = $.map(nested, function(item) { return item; });
Run Code Online (Sandbox Code Playgroud)

但是这种方法不适用于下划线的map函数.

那么我如何[1, 2, 3]使用underscore.js 获得扁平化数组呢?

Pat*_*ick 41

如果你有一个稍微复杂的数组,比如一个来自JSON的数组,你也可以利用pluck方法,提取你感兴趣的特定属性,类似于parents.SelectMany(parent => parent.Items);

// underscore version
var allitems = _.flatten(_.pluck(parents, 'items'));
Run Code Online (Sandbox Code Playgroud)

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)
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/lodash/4.16.6/lodash.min.js"></script>
<pre id="result"></pre>
Run Code Online (Sandbox Code Playgroud)


如果您想要做更多的事情并且不想链接运算符,您可以使用该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);
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
<pre id="result"></pre>
Run Code Online (Sandbox Code Playgroud)


arm*_*oon 40

var nested = [ [1], [2], [3] ];
var flattened = _.flatten(nested);
Run Code Online (Sandbox Code Playgroud)

这是一个小提琴

  • 注意:传递shallow = true,如果你只需要一个展平程度(比如SelectMany那样):`_ .flatten(nested,true)` (6认同)
  • [`flatten`](https://lodash.com/docs#flatten)现在默认只显示一个级别; 他们添加了"flattenDeep"和"flattenDepth". (2认同)