Javascript 如何使用 underscore.js 产生展平结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8786417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:30:38  来源:igfitidea点击:

How to use underscore.js to produce a flatten result

javascriptjsonunderscore.js

提问by Kuroro

The json object is

json对象是

var data = [{"Parent":1,"Child":[4,5,6]},{"Parent":2},{"Parent":3}]

How can I use underscore.js chain/map/pluck etc... function to get the flatten result

我如何使用 underscore.js chain/map/pluck 等...函数来获得展平结果

     var result = [];
for (var i = 0; i < data.length; i++) {
    result.push(data[i].Parent);
    if (data.Child != undefined) {
        for (var j = 0; j < data[i].Child.length; j++) {
            result.push(data[i].Child[j]);
        }
    }
}
console.log(result) >> //1,4,5,6,2,3

回答by georg

Here's a shorter solution:

这是一个较短的解决方案:

flat = _.flatten(_.map(data, _.values)) 

回答by Marl

Alternatively, if you want a function that can universally flatten any collection of objects or arrays,

或者,如果您想要一个可以普遍展平任何对象或数组集合的函数,

You could extend Underscore with:

您可以使用以下方式扩展下划线:

_.mixin({crush: function(l, s, r) {return _.isObject(l)? (r = function(l) {return _.isObject(l)? _.flatten(_.map(l, s? _.identity:r)):l;})(l):[];}});

Crush(for lack of a better name) can be called like _.crush(list, [shallow])or _(list).crush([shallow])and behaves exactly like a generalized form of Underscore's built-in Flatten.

Crush(因为没有更好的名字)可以像_.crush(list, [shallow])or_(list).crush([shallow])一样调用,其行为与 Underscore 的内置Flatten的广义形式完全一样。

It can be passed a collection of nested objects, arrays, or both of any depth and will return a single-leveled array containing all of the input's values and own properties. Like Flatten, if it is passed an additional argument which evaluates to true, a "shallow" execution is performed with the output only flattened one level.

它可以传递一组嵌套对象、数组或任何深度的集合,并将返回一个包含所有输入值和自己的属性的单级数组。与Flatten一样,如果传递了一个评估为真的附加参数,则执行“浅”执行,输出仅展平一级。

Example 1:

示例 1:

_.crush({
   a: 1,
   b: [2],
   c: [3, {
      d: {
         e: 4
      }
   }]
});

//=> [1, 2, 3, 4]

Example 2:

示例 2:

_.crush({
   a: 1,
   b: [2],
   c: [3, {
      d: {
         e: 4
      }
   }]
}, true);

//=> [1, 2, 3, {
//      d: {
//         e: 4
//      }
//   }]


An explanation of the code itself is as follows:

代码本身的解释如下:

_.mixin({  // This extends Underscore's native object.

  crush: function(list, shallow, r) {  // The "r" is really just a fancy
                                       // way of declaring an extra variable
                                       // within the function without
                                       // taking up another line.

    return _.isObject(list)?  // Arrays (being a type of object)
                              // actually pass this test too.

      (r = function(list) {  // It doesn't matter that "r" might have
                             // been passed as an argument before,
                             // as it gets rewritten here anyway.

        return _.isObject(list)?  // While this test may seem redundant at
                                  // first, because it is enclosed in "r",
                                  // it will be useful for recursion later.

          _.flatten(_.map(list, shallow?  // Underscore's .map is different
                                          // from plain Javascript's in
          // _.map will always return     // that it will apply the passed
          // an array, which is why we    // function to an object's values
          // can then use _.flatten.      // as well as those of an array.

            _.identity  // If "shallow" is truthy, .map uses the identity
                        // function so "list" isn't altered any further.

            : r  // Otherwise, the function calls itself on each value.
          ))
          : list  // The input is returned unchanged if it has no children.
        ;
      })(list)  // The function is both defined as "r" and executed at once.

      : []  // An empty array is returned if the initial input
    ;       // was something other than an object or array.
  }
});

Hope it helps if anyone needs it. :)

希望如果有人需要它会有所帮助。:)

回答by Tikhon Jelvis

Assuming you want to first get the parents and then get the children:

假设你想先得到父母,然后得到孩子:

_.chain(data).pluck("Parent")
             .concat(_.flatten(_(data).pluck("Child")))
             .reject(_.isUndefined)
             .value()

回答by Jenna Leaf

If you want to use underScore.js to flatten an array of many arrays into one array of elements, that's how you do it. Follow my example:

如果您想使用 underScore.js 将一个由多个数组组成的数组扁平化为一个元素数组,那么您就是这样做的。按照我的例子:

My graph has 2 series. Each series has a name and a sequence of datapoints {xtime, yValue}. My goal is to iron out all the data points from 2 series into one series of data points so to fill out a table.

我的图表有 2 个系列。每个系列都有一个名称和一系列数据点 {xtime, yValue}。我的目标是将 2 系列中的所有数据点整理成一系列数据点,以便填写表格。

var reducedArray = // flatten an array of series of data-objects into one series of data-objects
_.flatten( _.map( AllMySeries, function ( aSeries ) {
    return ( _.map( aSeries.dataPoints, function ( aPoint ) {
                return { curveID: aSeries.legendText, xT: aPoint.x, yVal: aPoint.y };
            } ) );
} ) );

My result :

我的结果:

'Series1','2017-04-19 08:54:19',1
'Series1','2017-04-19 08:59:19',0
'Series1','2017-04-19 09:04:19',1
'Series2','2017-04-19 08:54:19',1
'Series2','2017-04-19 08:59:19',0
'Series2','2017-04-19 09:04:19',1