How can I change the status property to false of each entry with let's say group "B", without changing the others? Either by mutating the array or returning a new one
const personnel = [
{ id: 0, name: "Audrey Holcomb", group: "A", status: true },
{ id: 1, name: "Gwendolyn Heath", group: "B", status: true },
{ id: 2, name: "Rivas Mclean", group: "C", status: true },
{ id: 3, name: "Valeria Schneider", group: "A", status: true },
{ id: 4, name: "Leticia Keith", group: "C", status: true },
{ id: 5, name: "Nadine Woodward", group: "B", status: true },
{ id: 6, name: "Shaffer Oliver", group: "A", status: true },
{ id: 7, name: "Meghan Norman", group: "B", status: true },
{ id: 8, name: "Kyle Smith", group: "C", status: true },
]
CodePudding user response:
Use map
and check for group
const update = (arr, group = "B", status = false) =>
arr.map((item) => ({
...item,
status: item.group === group ? status : item.status,
}));
const personnel = [
{ id: 0, name: "Audrey Holcomb", group: "A", status: true },
{ id: 1, name: "Gwendolyn Heath", group: "B", status: true },
{ id: 2, name: "Rivas Mclean", group: "C", status: true },
{ id: 3, name: "Valeria Schneider", group: "A", status: true },
{ id: 4, name: "Leticia Keith", group: "C", status: true },
{ id: 5, name: "Nadine Woodward", group: "B", status: true },
{ id: 6, name: "Shaffer Oliver", group: "A", status: true },
{ id: 7, name: "Meghan Norman", group: "B", status: true },
{ id: 8, name: "Kyle Smith", group: "C", status: true },
];
console.log(update(personnel))
console.log(update(personnel, "C", false))
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Loop through array, check if group is B and then change status to false
const personnel = [
{ id: 0, name: "Audrey Holcomb", group: "A", status: true },
{ id: 1, name: "Gwendolyn Heath", group: "B", status: true },
{ id: 2, name: "Rivas Mclean", group: "C", status: true },
{ id: 3, name: "Valeria Schneider", group: "A", status: true },
{ id: 4, name: "Leticia Keith", group: "C", status: true },
{ id: 5, name: "Nadine Woodward", group: "B", status: true },
{ id: 6, name: "Shaffer Oliver", group: "A", status: true },
{ id: 7, name: "Meghan Norman", group: "B", status: true },
{ id: 8, name: "Kyle Smith", group: "C", status: true },
];
for (let i = 0; i < personnel.length; i ) {
if (personnel[i]["group"] == "B") {
personnel[i]["status"] = false;
}
}
console.log(personnel);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You could use map to return a new array and modify the Group B elements as you go. This method doesn't have anything to recommend it over forEach in this particular instance, I don't think, but in more complicated circumstances it can be much simpler.
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
let changed = personnel.map(m=>{
m.status = m.group == 'B' ? false : m.status;
return m;
});
console.log(changed);
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
You might also create an arrow function to make things a little cleaner, and then since you are only using one line in map, you can omit return
and the curly braces:
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
const checkGroup=(a)=>{
a.status = a.group=='B' ? false : a.status;
return a;
};
let changed = personnel.map(m=>checkGroup(m));
console.log(changed);
<iframe name="sif4" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
For a little more extensibility, you can set up the helper function take an argument, say the target you want to change:
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
const checkGroup=(a,b)=>{
a.status = a.group==b ? false : a.status;
return a;
};
let changed = personnel.map(m=>checkGroup(m, 'B'));
console.log(changed);
<iframe name="sif5" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
And you might also tighten up that boolean logic to avoid the ternary operator, although in this particular case it will probably be harder to read and maintain than the other way, and it's only marginally shorter:
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
const checkGroup=(a,b)=>{
a.status = !(a.group==b || !a.status)
return a;
};
let changed = personnel.map(m=>checkGroup(m, 'B'));
console.log(changed);
<iframe name="sif6" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
But if your use case is really as simple as what you're describing, then you're going be hard pressed to beat forEach, which you can accomplish in one line:
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
personnel.forEach(m=>{m.status = m.group == 'B' ? false : m.status});
console.log(personnel);
<iframe name="sif7" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Another one line possibility is to use while with find to loop as long as the array contains an object where the group is B and the status is not false:
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
while(o = personnel.find(f=>f.group=='B'&&f.status)) { o.status = false; }
console.log(personnel);
let c = personnel.length;
while((o = personnel.find(f=>f.group=='B'&&f.status)) && c-->0) { o.status = false; }
console.log(personnel);
<iframe name="sif8" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Be aware that this can set you up with a non-terminating loop if you aren't careful and hang the whole code. It's good to put some failsafe condition in, for instance a counter that increments once per loop, and exit if you hit that condition. In the second variant of the while solution, I set c to personnel.length and decrement each loop, exiting once c drops below 0.
And don't forget the venerable and vanilla for
loop:
const personnel = [
{id: 0, name: 'Audrey Holcomb', group: 'A', status: true},
{id: 1, name: 'Gwendolyn Heath', group: 'B', status: true},
{id: 2, name: 'Rivas Mclean', group: 'C', status: true},
{id: 3, name: 'Valeria Schneider', group: 'A', status: true},
{id: 4, name: 'Leticia Keith', group: 'C', status: true},
{id: 5, name: 'Nadine Woodward', group: 'B', status: true},
{id: 6, name: 'Shaffer Oliver', group: 'A', status: true},
{id: 7, name: 'Meghan Norman', group: 'B', status: true},
{id: 8, name: 'Kyle Smith', group: 'C', status: true},
];
for(i=0; i<personnel.length; i ) {
personnel[i].status =
personnel[i].group == 'B' ?
false :
personnel[i].status
;
}
console.log(personnel);
<iframe name="sif9" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Now, don't sleep on those last two. They might not get a lot of love these EC6 days, but they will drastically outperform map, reduce, forEach, Object.keys(), etc. That usually isn't an issue, so it's probably better to code whatever is the easiest to read, maintain and extend, but it is good to be aware that those methods come with performance costs.
CodePudding user response:
personnel.map(item => {
if (item?.group === 'B') {
item.status = false;
}
});