How to use underscore.js to produce a flatten result

后端 未结 4 1452
抹茶落季
抹茶落季 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: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. :)

提交回复
热议问题