BattlFrog
BattlFrog

Reputation: 3397

Check jquery array of objects for matching key. += value if match, push new object if not

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

Answers (3)

adeneo
adeneo

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

kukkuz
kukkuz

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

Anurag Singh Bisht
Anurag Singh Bisht

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

Related Questions