JavaScript - 对对象数组中不同对象的相同ID的值求和

时间:2017-09-24 12:11:35

标签: javascript arrays

我的代码中有一个对象数组。对象具有相同的键,具有不同或相同的值。

'hr','management','qa'

数组如下所示:

enter image description here

我想迭代这个数组,如果对象中的Descriptions相同,那么 var a = []; a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'}); a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'20.00'}); a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'}); a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'75.00'}); console.log(a); 应该总结一下。

我尝试使用两个taxid循环并且它正在工作但在这种情况下,它正在检查自身的id并将值与自身相加。如下所示:

tax_value

感谢您的关注,谢谢。

9 个答案:

答案 0 :(得分:1)

你可以用不同的方式实现这一点。

一个是使用reduce:

a = a.reduce((c, i)=>{c[i.taxid]=(c[i.taxid]||0)+parseFloat(i.tax_value); return c}, {});

这对你来说过于复杂,你可以使用循环:

var t = {};
a.forEach((v)=>t[v.taxid]=(t[v.taxid]||0)+parseFloat(v.tax_value));
a = t;

如果表达式过于复杂,您可以使用简单的if条件来实现:

var t = {};
a.forEach((v)=>{
  if(t[v.taxid])
    t[v.taxid]+=parseFloat(v.tax_value);
  else
    t[v.taxid] = parseFloat(v.tax_value);
});
a = t;

编辑:响应问题和volitionaly输出的编辑: [{taxid : NUM, tax_value : NUM}, ...]

a = a.reduce((c, i)=>{
  let cc = c.findIndex((e)=>e.taxid==i.taxid);
  if(cc==-1) c.push({taxid: i.taxid, tax_value: parseFloat(i.tax_value)});
  else c[cc].tax_value += parseFloat(i.tax_value)
  return c
}, []);

答案 1 :(得分:1)

var output = a.reduce( (final,data) => {
 let isAlready = final.find( ( value ) => { 
   value.taxid == data.taxid;
 });
 if(!isAlready){
   final.push( data );
 } else {
   var index = final.indexOf(isAlready);
   final[index].tax_value = parseFloat(final[index].tax_value) + parseFloat(data.tax_value);
 }
 return final;
},[] )

答案 2 :(得分:1)

一些注意事项:

  • tax_value是一个字符串。您至少需要一个隐式类型转换来编号,因为如果您添加一个数字和一个字符串,该数字将转换为字符串,您将获得字符串连接,但不是算术运算。

  • 改变给定的数据结构或创建一个新的数据结构。在这种情况下,通常总是最好生成一个新的结果集,而不是将给定的结构用作数据和结果集。这可能会导致混淆,因为某些代码可能会在未更改的结构上进行转发。

解决方案

  • 在较新的系统(ES6)上使用哈希表(可能是Map或使用相同的taxid来保持对同一对象的引用。

    < / LI>
  • 使用unary plus +对隐含转换进行编号。

  • 使用单个循环。

&#13;
&#13;
var data = [{ taxid: 1, tax_name: 'VAT', tax_value:' 25.00' }, { taxid: 2, tax_name: 'Service Tax', tax_value: '20.00' }, { taxid: 1, tax_name: 'VAT', tax_value: '25.00' }, { taxid: 2, tax_name: 'Service Tax', tax_value: '75.00' }],
    hash = Object.create(null),
    result = [];

data.forEach(function (o) {
    if (!hash[o.taxid]) {
        hash[o.taxid] = { taxid: o.taxid, tax_name: o.tax_name, tax_value: 0 };
        result.push(hash[o.taxid]);
    }
    hash[o.taxid].tax_value += +o.tax_value;
});

console.log(result);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
&#13;
&#13;

答案 3 :(得分:1)

**您可以通过创建空对象并在每次迭代中开始初始化它来使用 forEach 循环来完成它,如果找到,它将检查出租车,然后将其添加到它,否则它将转到其他 **

    const a = [];
    a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
    a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'20.00'});
    a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
    a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'7.00'});    
    a.push({taxid : 3, tax_name: 'Service Tax', tax_value:'3.00'});

    let holders={};
    a.forEach(function (item) {
          if (holders.hasOwnProperty(item.taxid)) {
            holders[item.taxid] = holders[item.taxid] + parseFloat(item.tax_value);
          } else {
            holders[item.taxid] = parseFloat(item.tax_value);
          }
        });
        console.log(holders);

答案 4 :(得分:0)

您可以使用reduce并将值相加

var a = [];
a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'20.00'});
a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'75.00'});

let res = a.reduce((a, b) =>
  a.set(b.taxid, (a.get(b.taxid) || 0) + Number(b.tax_value)), new Map);

console.log(res);

如果要将生成的Map放到对象中,可以使用

toObject(map) {
    let obj = Object.create(null);
    for (let [key, value] of map.entries()) {
        obj[key] = value;
    }
    return obj;
} 

console.log(toObject(res));

答案 5 :(得分:0)

我认为你想要这样的东西作为你的实现。

&#13;
&#13;
var a = [];
        a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
        a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'20.00'});
        a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
        a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'75.00'});
        
//Sum up all the same taxid tax_value
var temp = {};
a.forEach(function(obj){
   if(!temp[obj.taxid]){
     temp[obj.taxid] = obj.tax_value;
   } else {
     temp[obj.taxid] = Number(temp[obj.taxid]) + Number(obj.tax_value);
   }
});

//Format the data into desired output
var result = [];
for(var key in temp){
  result.push({
    taxid: key,
    tax_value: temp[key]
  })
}

console.log(result)
&#13;
&#13;
&#13;

答案 6 :(得分:0)

只需在循环中添加另一个条件(第二个循环中的“if”语句)

(a[i]['taxid'] === a[j]['taxid'] && j !== i)

<强>解释
如你所说,循环是用自己检查id,为了防止这种情况,你可以添加“j!== i”,所以如果第二个循环从第一个循环中命中id,它将通过它,所以它不会自我总结

答案 7 :(得分:0)

这是一种可能的解决方案。它涉及将总和更改为对象,即var sum = {},然后将tax_value的总和添加到与其他对象匹配的任何ID。我尝试使用您的原始代码,但请记住,有更有效的解决方案。

PS:if语句中的a[i] !== a[j]阻止它自行检查'taxid'

var a = [];
a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'20.00'});
a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'75.00'});

var sum = {};
var res = 0;
var newArray = [];
for (var i=0; i<a.length;i++){
    for (var j=0;j<a.length;j++){
        if(a[i]['taxid']==a[j]['taxid'] && a[i] !== a[j]){
            sum[a[i]['taxid']] === undefined ? sum[a[i]['taxid']] = 0 : sum[a[i]['taxid']] += parseFloat(a[i]['tax_value']) + parseFloat(a[j]['tax_value']);
        }
    }
}

console.log(sum);

答案 8 :(得分:0)

蛋糕

&#13;
&#13;
const a = [];
a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'20.00'});
a.push({taxid : 1, tax_name: 'VAT', tax_value:'25.00'});
a.push({taxid : 2, tax_name: 'Service Tax', tax_value:'75.00'});


const sum = {};
for (var i = 0; i < a.length; i++) {
 const o = a[i];
 const lol = parseFloat(o.tax_value);
 sum[o.taxid] = (sum[o.taxid]) ? sum[o.taxid] + lol : lol;
}
console.log(sum);
&#13;
&#13;
&#13;