需要一个算法来操作javascript中的数组结构

时间:2011-11-28 11:36:11

标签: javascript

在javascript中,这是我的开始数组:

[{
   name: 'aaa',
   value: 1
 },
 {
   name: 'bbb',
   value: 0
 },
 {
   name: 'bbb',
   value: 1
}]

我希望将其转换为此数组:

[{
   name: 'aaa',
   value: 1
 },
 {
   name: 'bbb',
   value: [0, 1]
 }]

我需要一个好的简单算法来做到这一点

4 个答案:

答案 0 :(得分:2)

怎么样:

var array = [{
   name: 'aaa',
   value: 1
 },
 {
   name: 'bbb',
   value: 0
 },
 {
   name: 'bbb',
   value: 1
}];

var map = {};    
for(var i = 0; i < array.length; i++) {
  var name = array[i].name;
  if (map[name] === undefined) {
    map[name] = [];
  }
  map[name].push(array[i].value);
}

var result = [];
for(var key in map) {
  var value = map[key];
  result.push({
    name: key, 
    value: value.length === 1 ? value[0] : value
  });
}

最简单的方法是创建一个地图以跟踪使用的名称。然后将此映射转换回对象数组。

如果您想使用value的数组,请将其更改为:

result.push({
  name: key, 
  value: value
});

答案 1 :(得分:1)

这里是最简单实现的伪代码

hash = {}
for(pair in array) {
    hash[pair.name] ||= []
    hash[pair.name] << pair.value
}

result = []
for(k, v in hash) {
    result << {name: k, value: v}
}

答案 2 :(得分:0)

此功能可以解决这个问题

function consolidate(var arrayOfObjects)    
{
    // create a dictionary of values first
    var dict = {};
    for(var i = 0; i < arrayOfObjects.length; i++)
    {
        var n = arrayOfObjects[i].name;
        if (!dict[n])
        {
            dict[n] = [];
        }
        dict[n].push(arrayOfObjects[i].value);
    }

    // convert dictionary to array again        
    var result = [];
    for(var key in dict)
    {
        result.push({
            name: key,
            value: dict[key].length == 1 ? dict[key][0] : dict[key]
        });
    }

    return result;
}

答案 3 :(得分:0)

另一种解决方案:

function convert(arr) {
    var res = [];
    var map = {};

    for (var i=0;i<arr.length;i++) {
        var arrObj = arr[i];
        var oldObj = map[arrObj.name];
        if (oldObj == undefined) {
            oldObj = {name:arrObj.name, value:arrObj.value};
            map[arrObj.name] = oldObj;
            res.push(oldObj);
        } else {
            if( typeof oldObj.value === 'number' ) {
                oldObj.value = [oldObj.value];
            }
            oldObj.value.push(arrObj.value);
        }
    }
    return res;
}

理论上它应该工作得更快并且使用更少的内存。基本上它创建了一个结果数组和一个map,它是同一个数组的索引(没有重复的对象)。所以它在一次迭代而不是两次迭代中填充结果,并且不需要将map转换为数组(这节省了几个CPU周期:P)。

<强>加了: 如果value: [1]可以接受,则以下是该函数的变体:

function convert(arr) {
    var res = [];
    var map = {};

    for (var i=0;i<arr.length;i++) {
        var arrObj = arr[i];
        var oldObj = map[arrObj.name];
        if (oldObj == undefined) {
            oldObj = {name:arrObj.name, value:[arrObj.value]};
            map[arrObj.name] = oldObj;
            res.push(oldObj);
        } else {
            oldObj.value.push(arrObj.value);
        }
    }
    return res;
}