怎么实现数组内对象code值相同的情况下poll值进行累加

var arr = [

    {"code": "a", "poll": 7},
    {"code": "b", "poll": 2},
    {"code": "c", "poll": 18},
    {"code": "a", "poll": 5},
    {"code": "c", "poll": 12},
    {"code": "a", "poll": 1}
];

var arr2 = [

{"code": "a", "poll": 13},
{"code": "b", "poll": 2},
{"code": "c", "poll": 30}

];
如何实现arr → 到arr1 的转变,且code值 不仅仅为 a b c 也可能为 adsdsd dsdsd a223 任意值 如何实现 类似转变

阅读 4.7k
3 个回答

给你来一个不考虑性能的

var arr = [
  {"code": "a", "poll": 7},
  {"code": "b", "poll": 2},
  {"code": "c", "poll": 18},
  {"code": "a", "poll": 5},
  {"code": "c", "poll": 12},
  {"code": "a", "poll": 1}
];

let arr1 = arr.sort((pre, next) => pre.code > next.code).reduce((pre, v) => {
  let lastIndex = pre.length - 1;
  if (lastIndex >= 0 && pre[lastIndex].code === v.code) {
    pre[lastIndex].poll += v.poll;
  } else {
    pre.push(Object.assign({}, v));
  }
  return pre;
}, []);
console.log(arr1);

再来个一次遍历的,以空间换时间。

function pollAdd(arr) {
  let res = [];
  let tmp = {};

  arr.forEach((v) => {
    if (!tmp.hasOwnProperty(v.code)) {
      tmp[v.code] = res.length;
      return res.push(Object.assign({}, v));
    }
    res[tmp[v.code]].poll += v.poll;
  });

  return res;
}

我写了个解决的例子,参考一下。不过我要先讲一下,你的问题中就已经有错误的语法。物件字面定义不是这样用的,这像是JSON格式:

{"code": "a", "poll": 7}

这如果是JSON字串,要先解析为物件才是对的作法。

var jsonSample = '[{"code": "a", "poll": 7}]';

var arr = JSON.parse(jsonSample);;
console.log(arr);

//{code: 'a', poll: 7}

第一个例子的思路是很直觉的解决,用for语句寻遍整个原先的阵列(arr),另外用个新的阵列装找到的每个物件,如果发现在新阵列(arr2)中的物件中的code属性有相同的,就不新增,而是作poll属性的相加:

var arr2 = [];

// 这函数用来测试某个物件的code属性是不是已经在新阵列中,
// 如果有回传是哪个索引,没有则最后回传-1
function findIndex(value, array){
  for(var i=0; i< array.length; i++){
    if(array[i].code === value){
      return i;
    }
  }
  return -1;
}

var index = -1;
for(var i=0; i < arr.length; i++){

  index = findIndex(arr[i].code, arr2);
  
//这里判断后看物件是要进到新阵列,还是把新阵列中已有的物件中poll属性作相加
  if(index === -1){
    arr2.push(arr[i]);
  }else{
    arr2[index].poll +=arr[i].poll;
  }

}

console.log(arr2);

第二个例子的思路,是先不管新阵列长什么样,反正这里主要看的是物件中的code属性,相同的的code属性的值,要把对应的poll属性相加就是。所以先作这件事,最后再来组合新阵列。

//这个是用来运算arr的值的物件,会长得像{a: 12, b: 3}这样。
//也就是code属性的值与poll属性的值的组合
var obj={};

//寻遍arr物件的运算
for(var i=0; i< arr.length; i++){

   //物件中有这个属性,就作值的相加,没这属性把属性给赋值
  if(obj.hasOwnProperty(arr[i].code)){
    obj[arr[i].code] += arr[i].poll;
  }else{
    obj[arr[i].code] = arr[i].poll;
  }
}

//这里开始进行最后要输出的新阵列组合
var arr2=[];

//把obj物件中的属性与值拉出来,一个个推到(push)新阵列中
for(var prop in obj){
  arr2.push({
    code: prop,
    poll: obj[prop]
  });
}

console.log(arr2); 

会有第二种的思路是在js中有一些物件的内建运算符或方法,可以用得上,看起来代码行数会少些。稍微测了一下大数据(阵列中有100万与1000万笔物件,code只有10种情况时),第一种比较快,大约是第二种的3-4倍快,实际还是要看应用。

我没花太多时间再想太细,不过代码都有测过是可以正常运作,希望对你有帮得上忙了。有细部不理解可以再问。

测试代码:

var code = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];

var arr = [];

//i<50这里作加减可控制产生的物件数量
for(var i = 0, index = 0, number = 0; i< 50; i++){
  index = Math.floor(Math.random() * code.length);
  number = Math.floor(Math.random() * 20)+1;
  arr.push({
    code: code[index],
    poll: number
  });
}

var t0 = performance.now();

//要测试的代码写在这

var t1 = performance.now();

console.log('Call to doSomething took ' + (t1 - t0) + ' milliseconds.');

你这是js吧

    var arr = [
        {"code": "a", "poll": 7},
        {"code": "b", "poll": 2},
        {"code": "c", "poll": 18},
        {"code": "a", "poll": 5},
        {"code": "c", "poll": 12},
        {"code": "a", "poll": 1}
    ];
    var newArr = [];
    for (i in arr) {
        if(typeof(newArr[arr[i].code]) == 'undefined'){
            newArr[arr[i].code] = 0;
        }
        newArr[arr[i].code] += arr[i].poll;
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏