Glenn Joseph
Glenn Joseph

Reputation: 11

Updating an array which already exists and pushing new data into the same array

I wanted to push a arrays values into another array but also while pushing the data if already exiting data is available it should just update the existing data. The code is in typescript.


class itemList{
    constructor(public name: string, public amount: number){}
}

function DisArr(Ar1: itemList[]){
    for(let item of Ar1){
        console.log(item.name + " -- " + item.amount);
    }
}

var Ar1 = [new itemList('Apple',3),
new itemList('Tomato',4),
new itemList('Jam',1)];

var Ar2 = [new itemList('Orange',3),
new itemList('Tomato',8),
new itemList('Grape',20)];

console.log("Array before updating : ");
DisArr(Ar1);
Ar1.push(...Ar2);
console.log("Array before updating : ");
DisArr(Ar1);

As of now the output is: *Array before updating : Apple -- 3 Tomato -- 4 Jam -- 1

Array after updating : Apple -- 3 Tomato -- 4 Jam -- 1 Orange -- 3 Tomato -- 8 Grape -- 20*

But I want output as: *Array before updating : Apple -- 3 Tomato -- 4 Jam -- 1

Array after updating : Apple -- 3 Tomato -- 12 Jam -- 1 Orange -- 3 Grape -- 20*

How do I change the code as to get the desired output?

Upvotes: 1

Views: 66

Answers (3)

Hien Nguyen
Hien Nguyen

Reputation: 18975

I have another solution use reduce method and remove duplicate in Ar2 and concat them as below

let result = Ar1.reduce((acc, item) => {
      let found = Ar2.find(c => c.name == item.name);
      if (found != undefined) {
        item.amount += found.amount;
        const index = Ar2.indexOf(found);
        if (index > -1) {
          Ar2.splice(index, 1);
        }
      }
      acc.push(item);
      return acc;
    }, []);

    result = result.concat(Ar2);

Demo at stackbliz https://stackblitz.com/edit/angular-merge-array-reduce

Upvotes: 0

Ash
Ash

Reputation: 11472

My approach was to create a new function addToArrayOrIncrementAmount which accepts an array to modify (contextArray) and an array of new values to add (newArray).

For each item in newArray check if that item exists in contextArray, using the .name property as an identifier (should be a unique id). If that identifier does not exist than push a new item, otherwise modify/increment the amount value with +=. Call this new function like addToArrayOrIncrementAmount(Ar1, Ar2).

class itemList {
  constructor(public name: string, public amount: number) { }
}

function DisArr(Ar1: itemList[]) {
  for (let item of Ar1) {
    console.log(item.name + " -- " + item.amount);
  }
}

function addToArrayOrIncrementAmount(contextArray: itemList[], newArray: itemList[]) {
  newArray.forEach(product => {
    const index = contextArray.findIndex((e) => e.name === product.name);

    if (index === -1) {
      contextArray.push(product);
    } else {
      contextArray[index].amount += product.amount;
    }
  });
}

var Ar1 = [new itemList('Apple', 3),
  new itemList('Tomato', 4),
  new itemList('Jam', 1)
];

var Ar2 = [new itemList('Orange', 3),
  new itemList('Tomato', 8),
  new itemList('Grape', 20)
];

console.log("Array before updating : ");
DisArr(Ar1);
addToArrayOrIncrementAmount(Ar1, Ar2);
console.log("Array before updating : ");
DisArr(Ar1);

Here it is as a JavaScript version just so I could insert into the answer and be able to demonstrate it works by clicking "Run code snippet".

class itemList {
  constructor(name, amount) {
    this.name = name;
    this.amount = amount;
  }
}

function DisArr(Ar1) {
  for (let item of Ar1) {
    console.log(item.name + " -- " + item.amount);
  }
}

function addToArrayOrIncrementAmount(contextArray, newArray) {
  newArray.forEach(product => {
    const index = contextArray.findIndex((e) => e.name === product.name);

    if (index === -1) {
      contextArray.push(product);
    } else {
      contextArray[index].amount += product.amount;
    }
  });
}

var Ar1 = [new itemList('Apple', 3),
  new itemList('Tomato', 4),
  new itemList('Jam', 1)
];

var Ar2 = [new itemList('Orange', 3),
  new itemList('Tomato', 8),
  new itemList('Grape', 20)
];

console.log("Array before updating : ");
DisArr(Ar1);
addToArrayOrIncrementAmount(Ar1, Ar2);
console.log("Array before updating : ");
DisArr(Ar1);

Upvotes: 0

Glenn Joseph
Glenn Joseph

Reputation: 11

I did some changes in the code and i am getting the required answer but not sure if its the best solution. If anyone has better solution please do post your answer.


class itemList{
    constructor(public name: string, public amount: number){}
}

function DisArr(Ar1: itemList[]){
    for(let item of Ar1){
        console.log(item.name + " -- " + item.amount);
    }
}

var Ar1 = [new itemList('Apple',3),
new itemList('Tomato',4),
new itemList('Jam',1)];

var Ar2 = [new itemList('Orange',3),
new itemList('Tomato',8),
new itemList('Grape',20)];

console.log("Array before updating : ");
DisArr(Ar1);

var delAr = [];
for(let i=0; i<Ar2.length; i++){
    for(let obj of Ar1){
        if(obj.name === Ar2[i].name){
            obj.amount += Ar2[i].amount;
            delAr.push(i);
        }
    }
}
for(let no of delAr){
    Ar2.splice(no,1);
}
Ar1.push(...Ar2);


console.log("Array before updating : ");
DisArr(Ar1);
---

Upvotes: 0

Related Questions