Reputation: 116
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
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
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; }
.filter()
check how many time a value
is present in array1
array2
count.Upvotes: 1
Reputation: 37755
You can use reduce
and map
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