Aditya R
Aditya R

Reputation: 383

Javascript merging duplicates in an array of objects

I have an array of objects like this-

    {"zone":"lobby a","time":"00:00","hub":"I","Sum":0.0,"schedule":"2022"},
    {"zone":"lobby b","time":"00:01","hub":"I","Sum":1.0,"schedule":"112022"},
    {"zone":"lobby a","time":"00:01","hub":"I","Sum":2.0,"schedule":"11_2022"},
    {"zone":"lobby b","time":"00:03","hub":"I","Sum":0.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":1.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":2.0,"schedule":"11_2022"},

The duplicate 'time' needs to be merged by adding the sums only if the zone is same.

Result should be

    {"zone":"lobby a","time":"00:00","hub":"I","Sum":0.0,"schedule":"2022"},
    {"zone":"lobby b","time":"00:01","hub":"I","Sum":1.0,"schedule":"112022"},
    {"zone":"lobby a","time":"00:01","hub":"I","Sum":2.0,"schedule":"11_2022"},
    {"zone":"lobby b","time":"00:03","hub":"I","Sum":0.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":3.0,"schedule":"11_2022"},
      

Any help will be much appreciated. I have tried many options using maps etc, but have not been successful.

Upvotes: 2

Views: 140

Answers (3)

Andrew Parks
Andrew Parks

Reputation: 8087

const a = [
  {"zone":"lobby a","time":"00:00","hub":"I","Sum":0.0,"schedule":"2022"},
  {"zone":"lobby b","time":"00:01","hub":"I","Sum":1.0,"schedule":"112022"},
  {"zone":"lobby a","time":"00:01","hub":"I","Sum":2.0,"schedule":"11_2022"},
  {"zone":"lobby b","time":"00:03","hub":"I","Sum":0.0,"schedule":"11_2022"},
  {"zone":"lobby c","time":"00:04","hub":"I","Sum":1.0,"schedule":"11_2022"},
  {"zone":"lobby c","time":"00:04","hub":"I","Sum":2.0,"schedule":"11_2022"}
];

let r = [];
a.forEach(i => {
  let dup = r.find(j => j.zone===i.zone && j.time===i.time);
  if(dup) dup.Sum = (dup.Sum + i.Sum).toFixed(1);
  else r.push(i);
});
console.log(r);

Upvotes: 1

Ben Aston
Ben Aston

Reputation: 55729

The following function uses a grouping function to associate items with one another, and a merging function to perform the addition of the sums.

For each item in the data, the group is determined and the group is replaced by the result of the existing group merged with the current item in that group.

Time complexity is O(n) (one iteration to group the items, one iteration to enumerate the resulting grouped items).

const data = [
    {"zone":"lobby a","time":"00:00","hub":"I","Sum":0.0,"schedule":"2022"},
    {"zone":"lobby b","time":"00:01","hub":"I","Sum":1.0,"schedule":"112022"},
    {"zone":"lobby a","time":"00:01","hub":"I","Sum":2.0,"schedule":"11_2022"},
    {"zone":"lobby b","time":"00:03","hub":"I","Sum":0.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":1.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":2.0,"schedule":"11_2022"} ]

function groupAndMerge(data, groupFn, mergeFn) {
    const result = {}
    for(let d of data) {
        result[groupFn(d)] = mergeFn(d, result[groupFn(d)] || { Sum: 0 }) 
    }
    return Object.values(result)
}

const groupFn = ({zone, time}) => zone + time
const mergeFn = (a, b) => ({ ...a, Sum: a.Sum + b.Sum })
console.log(groupAndMerge(data, groupFn, mergeFn))

Upvotes: 1

Hans Murangaza DRCongo
Hans Murangaza DRCongo

Reputation: 860

let input = [
{"zone":"lobby a","time":"00:00","hub":"I","Sum":0.0,"schedule":"2022"},
    {"zone":"lobby b","time":"00:01","hub":"I","Sum":1.0,"schedule":"112022"},
    {"zone":"lobby a","time":"00:01","hub":"I","Sum":2.0,"schedule":"11_2022"},
    {"zone":"lobby b","time":"00:03","hub":"I","Sum":0.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":1.0,"schedule":"11_2022"},
    {"zone":"lobby c","time":"00:04","hub":"I","Sum":2.0,"schedule":"11_2022"},
    ]

    let cleared = [];

    input.map((item, index)=>{
    const dupl_index = cleared.findIndex(itm_ =>itm_.zone === item.zone && itm_.time === item.time);
    if(dupl_index === -1){
    cleared.push(item)
    }else{
    cleared[dupl_index].Sum = Number(cleared[dupl_index].Sum + item.Sum).toFixed(1)
    }
    })

    console.log(cleared)

Upvotes: 1

Related Questions