繁体   English   中英

JavaScript - 将对象数组中不同对象的相同 id 的值相加

[英]JavaScript - Sum the values of same ids of different objects in the array of objects

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

        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是相同的,那么tax_value应该相加。

我尝试使用两个for循环并且它正在工作,但在这种情况下,它正在用自己检查 id 并用它自己总结值。 像下面这样:

var sum = 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']){
            sum = a[i]['tax_value'] + a[j]['tax_value'];
        }
    }
    newArray.push({taxid : a[i]['taxid'], tax_value : sum});
}

感谢您的关注,谢谢。

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

一种是使用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;

编辑:为了回应问题的编辑和自愿输出: [{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
}, []);

您可以只使用 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));
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;
},[] )

一些考虑:

  • tax_value是一个字符串。 你至少需要一个隐式类型转换为数字,因为如果你添加一个数字和一个字符串,数字会被转换为字符串,你会得到一个字符串连接,但不是算术运算。

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

解决方案

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

  • 使用一元加号+隐式转换为数字。

  • 使用单个循环。

 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);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

**您可以通过创建空对象并在每次迭代中开始初始化它来使用 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);

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

 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)

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

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

解释
正如您所说,循环正在用自身检查 id,为了防止这种情况,您可以添加“j !== i”,因此如果第二个循环从第一个循环中命中 id,它将通过它,因此它不会自行求和

这是一个可能的解决方案。 它涉及将总和更改为一个对象,因此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);

蛋糕

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM