最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to break an array of objects into 2 arrays, using UnderscoreLoDash - Stack Overflow

programmeradmin1浏览0评论

I have an array of objects:

var arr = [
  {field1: value, field2: value, field3: value, field4: value},
  {field1: value, field2: value, field3: value, field4: value},
  {field1: value, field2: value, field3: value, field4: value}
];

I need to break it into 2 arrays of objects: one containing objects that have only field1 and field 3, and one containing objects that have all the rest. I'm trying to use Underscore (well, actually LoDash - but they're the same) and so far, all I got is:

var arr1 = [], arr2 = [];
_.forEach(arr, function(line) {
    arr1.push(_.pick(line, ['field1', 'field3']));
    arr2.push(_.omit(line, ['field1', 'field3']));
});

While this code works it strikes me as very inefficient. I'm sure I'm missing an Underscore function that can make my life easier, my code more readable, and my program more efficient.

I have an array of objects:

var arr = [
  {field1: value, field2: value, field3: value, field4: value},
  {field1: value, field2: value, field3: value, field4: value},
  {field1: value, field2: value, field3: value, field4: value}
];

I need to break it into 2 arrays of objects: one containing objects that have only field1 and field 3, and one containing objects that have all the rest. I'm trying to use Underscore (well, actually LoDash - but they're the same) and so far, all I got is:

var arr1 = [], arr2 = [];
_.forEach(arr, function(line) {
    arr1.push(_.pick(line, ['field1', 'field3']));
    arr2.push(_.omit(line, ['field1', 'field3']));
});

While this code works it strikes me as very inefficient. I'm sure I'm missing an Underscore function that can make my life easier, my code more readable, and my program more efficient.

Share Improve this question asked Aug 29, 2013 at 17:55 Traveling Tech GuyTraveling Tech Guy 27.9k25 gold badges116 silver badges166 bronze badges 2
  • What do you mean when you say inefficient? – tusharmath Commented Aug 29, 2013 at 18:05
  • Seems like many internal iterations occur. Since both US and LD say they have a better iteration implementation, I was wondering if there's a way to take advantage of it somehow. – Traveling Tech Guy Commented Aug 29, 2013 at 18:16
Add a ment  | 

6 Answers 6

Reset to default 2

I don't think this is easier to read or more efficient then what you have written. But it does use underscore.

var arrs = _.reduce(arr, function(memo, item){

  var firstArr = _.chain(_.first(memo)).push(_.pick(item, ['field1', 'field3'])).value();
  var secondArr = _.chain(_.last(memo)).push(_.omit(item, ['field1', 'field3'])).value();

  return [ firstArr, secondArr ];

}, [[], []]);
var input = [
  {field1: value, field2: value, field3: value, field4: value},
  {field1: value, field2: value, field3: value, field4: value},
  {field1: value, field2: value, field3: value, field4: value}
];

/* Generic function to get key-value pair form array of object.
 input >> is array of object.
 keys >> array of string keys.
 isNotRequired >> boolean flag whether output contains the keys which are provided or the keys except which are provided.
*/

function getKeyValues(input, keys, isNotRequired) {
    if (!keys || !keys.length) {
        return input;
    }
    return _.reduce(input, function(output, values) {
        output.push(_.reduce(values, function(object, value, key) {
            if (!isNotRequired) {
                if (keys.indexOf(key) > -1) {
                    object[key] = value;
                }
            } else if (keys.indexOf(key) === -1) {
                object[key] = value;
            }
            return object;
        }, {}));
        return output;
    }, []);
}

//In your example hot to use the function:

var FirstArrayWithField1AndField2 = getKeyValues(input,['field1','field2']);
var SecondArrayWithoutField1AndField2 = getKeyValues(input,['field1','field2'],true);

Underscore uses native Array.prototype.forEach method for its alias _.forEach. If it is not present somehow then it would define its own forEach iterator using the simple for loop. Apparently the performance of native forEach isn't that great to the simple for loop. That's because the native forEach performs a lot of checks while iterating.

I can only suggest that you re define _.forEach method like this -

_.forEach = function(obj, iterator, context) {
    if (obj == null) return;
    if (obj.length === +obj.length) {
        for (var i = 0, l = obj.length; i < l; i++) {
            if (iterator.call(context, obj[i], i, obj) === breaker) return;
        }
    }
}

Hope this answers your question. Happy Coding!

var arrs = _.groupBy(arr, function(obj) {
    return 'field1' in obj && 'field3' in obj;
});

This will return an object with properties named true and false.

var i ,target,length = arr.length, arr1 = [], arr2 = [];
for(i = 0; i< length;i++){
  target = arr[i];
  arr1.push({
    field1: target.field1, 
    field3: target.field3:
  });
  arr2.push({
    field2: target.field2, 
    field4: target.field4:
  });
}
var myarr = 
[
      {'field1': 'val01', 'field2': 'val02', 'field3': 'val03', 'field4': 'val04'},
      {'field1': 'val11', 'field2': 'val12', 'field3': 'val13', 'field4': 'val14'},
      {'field1': 'val21', 'field2': 'val22', 'field3': 'val23', 'field4': 'val24'},
      {'field1': 'val31', 'field2': 'val32', 'field3': 'val33', 'field4': 'val34'}
];

var fields13 = [];
var fields24 = [];


_.each(myarr, function(myobj) 
{ 
      fields13.push(myobj.field1);
      fields24.push(myobj.field2);
      fields13.push(myobj.field3);
      fields24.push(myobj.field4);
});

console.log(fields13);
console.log(fields24);
发布评论

评论列表(0)

  1. 暂无评论