![](/img/trans.png)
[英]Sum JavaScript object propertyA values with the same object propertyB in an array of objects
[英]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
是一个字符串。 你至少需要一个隐式类型转换为数字,因为如果你添加一个数字和一个字符串,数字会被转换为字符串,你会得到一个字符串连接,但不是算术运算。
改变给定的数据结构或创建一个新的数据结构。 在这种情况下,通常情况下,最好生成一个新的结果集,而不是将给定的结构用作数据和结果集。 这可能会导致混淆,因为某些代码可能会依赖未更改的结构。
解决方案
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.