Reputation: 3397
User will fill in a table of data, then I need to iterate the table, group the byt he id and make sure each group == 100.
My plan is to loop through the table rows, make the key:value object, check the array for matching key. If the key matches, then add the value to the existing array object. If no match, push the new item.
Assuming this array:
var gidArr =
[
{
gid: '123',
ratio: '20'
},
{
gid: '123',
ratio: '40'
},
{
gid: '432',
ratio: '50'
},
]
the result should be:
{ gid:123, ratio:60 },
{ gid:432, ration: 50}
Couple things I have tried:
function GIDRatio(gid, ratio) {
this.gid = gid;
this.ratio = parseFloat(ratio);
}
var item = new GIDRatio(gid, ratio);
1:
if(gid in gidArr) {
gidArr.ratio += item.ratio;
} else {
gidArr.push(item);
}
2:
$.each(gidArr, function(i, v) {
if(v.gid === item.gid) {
v.ratio += item.ratio;
} else {
gisArr.push(item);
}
})
Fiddle: https://jsfiddle.net/8vw4eehs/11/
Upvotes: 1
Views: 2064
Reputation: 318322
var gidArr = [
{gid: '123', ratio: '20'},
{gid: '123', ratio: '40'},
{gid: '432', ratio: '50'},
{gid: '123', ratio: '40'}
];
/* Creating an array of objects */
var obj = gidArr.reduce((a,b) => (a[b.gid] = b.gid in a ? a[b.gid]+(+b.ratio):(+b.ratio), a),{});
var arr = Object.keys(obj).map(x => ({[x]:obj[x]}));
console.log(arr, "\n---------------------------")
/* Filtering based on values being 100 */
var result = arr.filter( o => Object.values(o)[0] === 100 );
console.log(result)
.as-console-wrapper {max-height: 100%!important; top: 0}
Upvotes: 0
Reputation: 42360
Use Array.prototype.reduce
to covert into a hashtable
and then accumulate the ratio
- see demo below:
var gidArr=[{gid:'123',ratio:'20'},{gid:'123',ratio:'40'},{gid:'432',ratio:'50'}];
var hash = gidArr.reduce(function(p,c){
if(p[c.gid])
p[c.gid].ratio += +c.ratio;
p[c.gid] = p[c.gid] || c;
p[c.gid].ratio = +p[c.gid].ratio;
return p;
},Object.create(null))
var result = Object.keys(hash).map(function(e){
return hash[e];
});
console.log(result);
Upvotes: 0
Reputation: 2753
You can make use of Array.reduce
method to convert your original array into a new structure.
Inside your reduce
function, just check if acc
i.e., your accumulated array
has gid
already available. If not then push in the array. If yes, then calculate the total of ratio
and update the ratio
.
var gidArr =
[
{
gid: '123',
ratio: '20'
},
{
gid: '123',
ratio: '40'
},
{
gid: '432',
ratio: '50'
},
];
const newArr = gidArr.reduce((acc, cur) => {
if(acc.some(x => x.gid === cur.gid)) {
acc.map(x => {
if(x.gid === cur.gid) {
x.ratio = (+x.ratio) + (+cur.ratio);
}
return x;
});
} else {
acc.push(cur);
}
return acc;
},[])
console.log(newArr);
Upvotes: 2