How to Avoid Array Mutation
Helder Burato Berto
Posted on April 2, 2020
On this article, I'll focus on showing how to add, edit and remove items in an array causing mutation and non-mutation ways.
One thing we need to keep in mind when writing code avoiding mutation is to return a new reference to the data after the update.
It's a common approach when working with functional programming and if you want to understand some concepts of functional programming I recommend you read this article I wrote some time ago.
Why Avoid Mutation
When you work with immutable data you can have some positive impacts like the following:
- Tracking data without mutation is much better;
- Immutable states help you implement unidirectional data flow that helps you handle data;
I really recommend you read this article go deeper into why avoid mutation.
Causing Mutation
The following steps will cause mutation into the array adding, removing and editing elements from family
.
To show an example of mutating, we'll use the following array:
const heroesMutate = ['Spider-man', 'Thor', 'Hulk', 'Iron Man'];
console.log(heroesMutate); // => ["Spider-man", "Thor", "Hulk", "Iron Man"]
Including in Array
Methods that will be used:
See the following use-case examples for these methods:
heroesMutate.push('Captain Marvel');
console.log(heroesMutate); // => ["Spider-man", "Thor", "Hulk", "Iron Man", "Captain Marvel"]
heroesMutate.unshift('Deadpool');
console.log(heroesMutate); // => ["Deadpool", "Spider-man", "Thor", "Hulk", "Iron Man", "Captain Marvel"]
heroesMutate.splice(2, 0, 'Black Panther');
console.log(heroesMutate); // => ["Deadpool", "Spider-man", "Black Panther", "Thor", "Hulk", "Iron Man", "Captain Marvel"]
Editing the Array
The following case will find index for the element we want to edit and set value to the found index:
const indexDeadpool = heroesMutate.indexOf('Deadpool');
heroesMutate[indexDeadpool] = 'Wolverine';
console.log(heroesMutate); // => ["Wolverine", "Spider-man", "Black Panther", "Thor", "Hulk", "Iron Man", "Captain Marvel"]
Removing in the Array
Methods that will be used:
See the following use-case examples for these methods:
heroesMutate.pop();
console.log(heroesMutate); // => ["Wolverine", "Spider-man", "Black Panther", "Thor", "Hulk", "Iron Man"]
heroesMutate.shift();
console.log(heroesMutate); // => ["Spider-man", "Black Panther", "Thor", "Hulk", "Iron Man"]
heroesMutate.splice(1, 1);
console.log(heroesMutate); // => ["Spider-man", "Thor", "Hulk", "Iron Man"]
Avoiding Mutation
In this topic, we'll add, remove and edit, avoiding mutations.
Methods that will be used:
- Array.prototype.slice();
- Array.prototype.concat();
- Array.prototype.map();
- Array.prototype.filter();
- Spread syntax;
See the following use-cases:
const villains = ['Loki', 'Thanos', 'Venom', 'Abomination'];
Including in the Array
Add to the end of array:
const newVillains = villains.concat('Juggernaut');
const newVillains2 = [...newVillains, 'Magneto'];
const newVillains3 = ['Red Skull', ...newVillains2];
console.log(villains); // => ["Loki", "Thanos", "Venom", "Abomination"]
console.log(newVillains); // => ["Loki", "Thanos", "Venom", "Abomination", "Juggernaut"]
console.log(newVillains2); // => ["Loki", "Thanos", "Venom", "Abomination", "Juggernaut", "Magneto"]
console.log(newVillains3); // => ["Red Skull", "Loki", "Thanos", "Venom", "Abomination", "Juggernaut", "Magneto"]
In the following example we'll add Ultron
after Thanos
in the array:
const newVillains = [...villains.slice(0, 2), 'Ultron', ...villains.slice(2, villains.length)];
console.log(villains); // => ["Loki", "Thanos", "Venom", "Abomination"]
console.log(newVillains); // => ["Loki", "Thanos", "Ultron", "Venom", "Abomination"]
Editing the Array
In the following example we'll edit Venom
to Galactus
:
const indexVenom = villains.indexOf('Venom');
const newVillains = [...villains.slice(0, indexVenom), 'Galactus', ...villains.slice(indexVenom+1)];
const newVillains2 = newVillains.map(v => v === 'Abomination' ? 'Ultron' : v);
console.log(villains); // => ["Loki", "Thanos", "Venom", "Abomination"]
console.log(newVillains); // => ["Loki", "Thanos", "Galactus", "Abomination"]
console.log(newVillains2); // => ["Loki", "Thanos", "Galactus", "Ultron"]
Removing in the Array
In the following example we'll remove Thanos
from the array:
const indexThanos = villains.indexOf('Thanos');
const newVillains = [...villains.slice(0, indexHelder), ...villains.slice(indexHelder+1)];
const newVillains2 = newVillains.filter(v => v !== 'Thanos');
console.log(villains); // => ["Loki", "Thanos", "Venom", "Abomination"]
console.log(newVillains); // => ["Loki", "Venom", "Abomination"]
console.log(newVillains2); // => ["Loki", "Abomination"]
See that in all the examples that we developed above, a new instance of the array was created, thus avoiding the mutation of the initially defined arrays.
Wrapping Up
Avoiding mutations is a safe and one-way path.
When you realize that you're writing code observing this type of detail, believe me, you will be writing better, secure code and avoiding possible bugs due to mutation.
Feel free to share your feedback and experience in the comments.
Enjoy programming! ✨
References
Array - JavaScript | MDN;
Marvel Teams, Groups, Squads, & Alliances;
Posted on April 2, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
August 16, 2020