How to use underscore.js to produce a flatten result

后端 未结 4 1430
抹茶落季
抹茶落季 2020-12-30 23:53

The json object is

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

How can I use underscore.js chain/map/pluck

相关标签:
4条回答
  • 2020-12-31 00:15

    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:

    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.

    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  
    
    0 讨论(0)
  • 2020-12-31 00:16

    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()
    
    0 讨论(0)
  • 2020-12-31 00:19

    Here's a shorter solution:

    flat = _.flatten(_.map(data, _.values)) 
    
    0 讨论(0)
  • 2020-12-31 00:24

    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.

    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.

    Example 1:

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

    Example 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. :)

    0 讨论(0)
提交回复
热议问题