如何使用Underscore / LoDash将对象数组分成2个数组

时间:2013-08-29 17:55:44

标签: javascript underscore.js lodash

我有一个对象数组:

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}
];

我需要将它分成2个对象数组:一个包含只包含field1和field3的对象,另一个包含具有所有其余对象的对象。我正在尝试使用下划线(嗯,实际上是LoDash - 但它们是相同的)到目前为止,我得到的只是:

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

虽然这段代码有效,但它效率很低。我确信我错过了一个可以让我的生活更轻松,我的代码更具可读性,我的程序更高效的下划线功能。

6 个答案:

答案 0 :(得分:2)

我认为这比你写的更容易阅读或更有效。但它确实使用下划线。

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 ];

}, [[], []]);

答案 1 :(得分:2)

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;
    }, []);
}

//在你的例子中使用函数hot:

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

答案 2 :(得分:1)

Underscore使用原生Array.prototype.forEach方法作为别名_.forEach。如果它不存在,那么它将使用简单的for循环定义自己的forEach迭代器。显然,原生forEach isn't that great对简单for循环的性能。这是因为原生forEach在迭代时执行lot of checks

我只能建议你像这样定义_.forEach方法 -

_.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;
        }
    }
}

希望这能回答你的问题。快乐的编码!

答案 3 :(得分:0)

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

这将返回一个名为truefalse的属性的对象。

答案 4 :(得分:0)

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:
  });
}

答案 5 :(得分:-1)

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);