Sallu
Sallu

Reputation: 116

update a property in object array

Is there a way to update a property in object array based on the number of times some other property is present as element in some other array

I have 2 arrays, array1 and array2:

var array1 = ["JOHN", "JACK", "JACK"];
var array2 = [
  {count: 9, value: "JACK"},
  {count: 9, value: "JOHN"},
  {count: 2, value: "TEST"}
];

Expected output :

[
  {count: 7, value: "JACK"}, // count = 9 - 2
  {count: 8, value: "JOHN"}, // count = 9 - 1
  {count: 2, value: "TEST"}
]

In array1, "JACK" is present twice, so I need to reduce count by 2, similarly "JOHN" is present once and hence its reduced by 1, "TEST" is not present so unchanged.

I tried the following

array1.map(item => {
  return array2.find( p => p["value"] === item);
});

With this, I am getting the below output,

[
  {count: 9, value: "JOHN"},
  {count: 9, value: "JACK"},
  {count: 9, value: "JACK"}
]

I am not sure whether it can be achieved using single lambda expression.

Thanks in advance!

Upvotes: 4

Views: 92

Answers (3)

mplungjan
mplungjan

Reputation: 177692

Assuming you are allowed to change the original array. ALSO assuming we are not talking 10s of thousand entries since I look up the value in the name array each time:

var array1  =  ["JOHN", "JACK", "JACK"];
var array2  = [{count: 9, value: "JACK"},
       {count: 9, value: "JOHN"},
       {count: 2, value: "TEST"}]

array2.forEach(item => item.count -= array1.filter(val => val === item.value).length);

console.log(array2);

Less resources:

var array1  =  ["JOHN", "JACK", "JACK"];
var array2  = [{count: 9, value: "JACK"},
       {count: 9, value: "JOHN"},
       {count: 2, value: "TEST"}]

// create lookup table
const names = array1.reduce((arr,cur) => { arr[cur] = (arr[cur]||0) + 1;  return arr;},{})
// subtract if present
array2.forEach(item => item.count -= (names[item.value] || 0));

console.log(array2);

Upvotes: 1

palaѕн
palaѕн

Reputation: 73896

You can get the result using array .map() and .filter() methods, assuming you are not allowed to change the original array:

var array1  =  ["JOHN", "JACK", "JACK"];
var array2  = [{count: 9, value: "JACK"}, {count: 9, value: "JOHN"}, {count: 2, value: "TEST"}]
       
var result = array2.map(({value, count}) => ({value, count: count - array1.filter(a=>a===value).length}))
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }

  • Using .filter() check how many time a value is present in array1
  • Then subtract that result from current array2 count.
  • Then just return a new array of objects with the updated count.

Upvotes: 1

Code Maniac
Code Maniac

Reputation: 37755

You can use reduce and map

  1. Loop over array1 and create a mapper object with names as key and repetition of names as value
  2. Loop over array2 and see if the name is present in mapper subtract respective value from

const array1 = ["JOHN", "JACK", "JACK"];
const array2 = [{count: 9, value: "JACK"},{count: 9, value: "JOHN"},{count: 2, value: "TEST"}]

const mapper = array1.reduce((op, inp) => {
  op[inp] = op[inp] || 0;
  op[inp]++;
  return op;
}, Object.create(null))

let final = array2.map(({count,value}) =>({
    value,
    count: count - (mapper[value] || 0)
}))

console.log(final)

Upvotes: 1

Related Questions