Reputation: 2042
I would like to filter an array of objects and update some value on the filtered entries. Here is my original code, without filtering:
let obj = {
foo: [
{
bar: "I should be modified",
modify: true,
},{
bar: "I should not be modified",
modify: false,
},{
bar: "I should be modified",
modify: true,
},
],
};
obj.foo.forEach((item, i) => {
let newItem = Object.assign({}, item);
newItem.bar = "I have been modified";
obj.foo[i] = newItem;
});
console.log(obj.foo);
/* Output:
[
{
bar: "I have been modified",
modify: true,
},{
bar: "I have been modified",
modify: false,
},{
bar: "I have been modified",
modify: true,
},
],
*/
Now I would like to replace .forEach(...
with .filter(e => e.modify).forEach(...
. So instead of modifying all the elements of obj.foo
, only those with modify === true
are modified. How can this be done without filtering again inside the forEach loop?
obj.foo.filter(e => e.modify).forEach((item, i) => {
let newItem = Object.assign({}, item);
newItem.bar = "I have been modified";
obj.foo[i] = newItem; // will not work as the index i is not correct from the original array
});
console.log(obj.foo);
/* Expected output:
[
{
bar: "I have been modified",
modify: true,
},{
bar: "I should not be modified",
modify: false,
},{
bar: "I have been modified",
modify: true,
},
],
*/
/* Actual output:
[
{
bar: "I have been modified",
modify: true,
},{
bar: "I have been modified",
modify: true,
},{
bar: "I should be modified",
modify: true,
},
],
*/
Upvotes: 1
Views: 1291
Reputation: 1275
So after read all the comments, that you don't want if-statement in it and other things, then this idea comes to my mind, without changing too much of your code, why don't let each item takes it's own original index, after modified, delete the idx property:
let obj = {
foo: [
{
bar: "I should be modified",
modify: true,
},{
bar: "I should not be modified",
modify: false,
},{
bar: "I should be modified",
modify: true,
},
],
};
let index = 0;
obj.foo.filter(e => ++index && e.modify && (e.idx = index)).forEach((item, i) => {
let newItem = Object.assign({}, item);
newItem.bar = "I have been modified";
obj.foo[newItem.idx - 1] = newItem;
delete newItem.idx;
});
console.log(obj.foo);
Upvotes: 0
Reputation: 1
This can also be done like this:
obj.foo.filter(e => e.modify).map((item) => {
item.bar = "I have been modified"
});
I think this should help.
Upvotes: 0
Reputation: 100
let obj = {
foo: [
{
bar: "baz",
modify: true,
},{
bar: "bad",
modify: false,
},{
bar: "hello",
modify: true,
},
],
};
const {foo} = obj;
const t = foo.reduce((acc, curr) => {
if (curr.modify) {
curr.bar = "I have been modified";
acc.push(curr);
}
return acc;
}, []);
console.log(t)
Upvotes: 1