如何操作数组对象并创建新数组

时间:2014-09-15 12:22:10

标签: javascript arrays

我有js数组,如下所示:

var names = [{name:"high",id:1},{name:"high",id:2}, 
{name:"low",id:1},  {name:"low",id:2},{name:"medium",id:1},{name:"medium",id:2}];

我需要像这样创建另一个数组。

var newArr=[{name:high,items:[1,2]},{name:low,items:[1,2]},{name:medium,items:[1,2]}];

请建议我怎么做。

4 个答案:

答案 0 :(得分:2)

基于

Underscorejs的解决方案

var obj = {};

_.each(names, function (e) {
    var o = obj[e.name];
    if (o) {
        o.items.push(e.id);
    } else {
        o = {name: e.name, items: [e.id]};
    }
    obj[e.name] = o;
});

var result = _.map(obj, function (e) {return e;});

纯粹的js

var obj = {};
for (var i = 0; i < names.length; i++) {
    var e = names[i];
    var o = obj[e.name];
    if (o) {
        o.items.push(e.id);
    } else {
        o = {name: e.name, items: [e.id]};
    }
    obj[e.name] = o;
}
var result = [];
for (var k in obj) {
    if (obj.hasOwnProperty(k)) {
        result.push(obj[k]);
    }
};

答案 1 :(得分:1)

这是一个简单易懂的解决方案,没有外部库。

var newArr = []
for ( var i in names ) {
    var exists = findItemInArray(names[i].name,newArr);
    if(exists) {                // Another item with same name was added to newArray
       var items = exists.items.push(names[i].id);    // We add the id to existing item
    } else {                   // No other item with same name was added to newArray
       var newItem = {name:names[i].name, items:names[i].id};
       newArr.push(newItem);
    }
}

如果项目已存在于newArray

中,我将此函数返回
function findItemInArray(name,array){
    for(var i in array){
       if(array[i].name === name){
           return array[i];
       }
    return null;
}

答案 2 :(得分:1)

这是一个不使用外部库的解决方案:

/**
 * Add the given object to the given set.
 *
 * @param {object} theSet The set to add this object to.
 * @param {object} theObject The object to add to the set.
 *
 * @return {object} theSet, with theObject added to it.
 *
 * @note Assumes that theObject.name should be the key,
 *       while theObject.id should go into the value array.
 * @note This is an Array.prototype.reduce() callback.
 */
function collect(theSet, theObject) {
    if (theSet.hasOwnProperty(theObject.name)) {
        theSet[theObject.name].push(theObject.id);
    } else {
        theSet[theObject.name] = [theObject.id];
    }
    return theSet;
}
var names = [{name:"high",id:5},{name:"high",id:6}, 
             {name:"low",id:1},  {name:"low",id:2},{name:"medium",id:3},{name:"medium",id:4}],
    combinedSet = names.reduce(collect, {}), // This is Step 1
    final = [],
    key;

// This is Step 2
for (key in combinedSet) {
    if (combinedSet.hasOwnProperty(key)) {
        final.push(
            {
                "name" : key,
                "items": combinedSet[key]
            }
        );
    }
}

第一步是将ID分组到对象名称下。我使用Array.prototype.reduce来执行此操作,并使用回调collect。转换的结果进入combinedSet变量。

第二步是获取我们在步骤1中创建的集合并将其转换为最终数组:使用集合键作为name成员创建对象,并将其值用作{ {1}}成员。我不能像以前那样使用items,所以我选择了一个简单的reduce循环。请注意,我使用for支票对事件进行了整理,以防止有人修改了hasOwnProperty;如果我没有这样做,那么集合中可能会有更多项目没有放在那里,这会引入错误。

答案 3 :(得分:0)

您正在寻找分组功能。试试underscoreJs groupBy

jsFiddle

var names = [{name:"high",id:1},{name:"high",id:2}, {name:"low",id:1},  {name:"low",id:2},{name:"medium",id:1},{name:"medium",id:2}];

console.debug(_.groupBy(names, 'name'));
// Object {high: Array[2], low: Array[2], medium: Array[2]}, where each item in the nested arrays refers to the original object