2017-09-24 59 views
-1

我的代码中有一个对象数组。对象具有不同或相同值的相同键。JavaScript - 总结对象数组中不同对象的相同ID的值

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

数组看起来如下:

enter image description here

我想通过这个数组迭代,如果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}); 
} 

我感谢您的关注,谢谢。

+2

请发表您的两个'for'循环。 –

+0

好吧..我正在更新这个问题 –

回答

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; 
},[]) 
+1

改变比较回调函数中的值不是一种好的编码风格。这是一个快速而肮脏的解决方案,但对于如此简单的代码片段来说并不是必需的。它违背了'find'函数的意义。没有downvote,因为它的工作原理,但我不喜欢的解决方案。 –

+0

谢谢,我刚更新了我的答案。 –

+0

我有点修改它,它的工作,谢谢你.. –

0

您可以通过不同方式实现此目的。

一个AY是使用减少:

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

是,这是太complecated你,你可以使用一个循环:

var t = {}; 
a.forEach((v)=>t[v.taxid]=(t[v.taxid]||0)+parseFloat(v.tax_value)); 
a = t; 
如果表达式太complecated的

,你可以achive这与一个简单的条件如下:

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 
}, []); 
0

你可以使用减少,如果你想要得到的结果映射到的值相加在一起

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

一个物体,你可以用

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

console.log(toObject(res)); 
0

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

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)

0

添加另一条件,你的循环( “如果”,在第二循环语句)

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

解释
如你所说,循环检查ID本身,为了防止这种情况,你可以添加“j!== i”的,所以如果第二环路命中从第一环路ID它将越过它,所以它不会总结本身

+0

我认为这个条件不是循环,而是if语句。您还应该解释为什么此修改可行。 – clemens

+1

我认为这是很明显的,应该修改if语句循环,并通过循环我的意思是他的解决方案,这是完全有效的,只需要一点波兰语,无论如何感谢提示,我真的应该写为什么这是工作 – erhardos

0

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

PS:在if语句中阻止它从检查'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);

0

蛋糕

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

0

一些注意事项:

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

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

  • 使用哈希表,这可能是在较新的系统(ES6)或用于保持参考同一个对象具有相同taxid对象的Map

  • 使用含有隐含号码的转换号码unary plus +

  • 使用单个循环。

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

相关问题