Skip to content

Instantly share code, notes, and snippets.

@jherr
Last active April 12, 2024 06:52
Show Gist options
  • Save jherr/0f40e9dc60836a1a36c237e094401c93 to your computer and use it in GitHub Desktop.
Save jherr/0f40e9dc60836a1a36c237e094401c93 to your computer and use it in GitHub Desktop.

Frameworks like React require that when you change the contents of an array or object you change its reference. Or push another way that you don't change arrays but instead create new arrays with updated values (i.e. immutability).

There are older array methods that are incompatible with immutability because they alter the array in place and don't change the array reference. These are mutable (or destructive) methods.

Shown below are replacements for the array destructive methods (e.g. push, pop, splice, sort, etc.) that will create new array references with the updated data.

Solutions are provided using the spread operator and also the newer "change array by copy" methods (toSpliced, toSorted, toReversed and with).

Setting Value At Index

Destructive version:

const myArray = [1, 3, 2];
myArray[1] = 10; // [1, 10, 2]

Non-destructive versions:

const myArray = [1, 3, 2];
const newArray = [...myArray];
newArray[1] = 10;

Or:

const myArray = [1, 3, 2];
const newArray = [
  ...myArray.slice(0, 1),
  10,
  ...myArray.slice(2, myArray.length)
];

Or (if you have access to with):

const myArray = [1, 3, 2];
const newArray = myArray.with(1, 10);

Push

Destructive version:

const myArray = [1, 3, 2];
myArray.push(5); // [1, 3, 2, 5]

Non-destructive versions:

const myArray = [1, 3, 2];
const newArray = [...myArray, 5];

Or (if you have access to toSpliced):

const myArray = [1, 3, 2];
const newArray = myArray.toSpliced(myArray.length, 0, 5);

Pop

Destructive version:

const myArray = [1, 3, 2];
const poppedValue = myArray.pop(); // [1, 3]

Non-destructive versions:

const myArray = [1, 3, 2];
const poppedValue = myArray[myArray.length - 1];
const newArray = myArray.slice(0, myArray.length - 1);

Or (if you have access to toSpliced):

const myArray = [1, 3, 2];
const poppedValue = myArray[myArray.length - 1];
const newArray = myArray.toSpliced(myArray.length - 1, 1);

Shift

Destructive version:

const myArray = [1, 3, 2];
const shiftedValue = myArray.shift(); // [3, 2]

Non-destructive version:

const myArray = [1, 3, 2];
const [shiftedValue, ...newArray] = myArray;

Unshift

Destructive version:

const myArray = [1, 3, 2];
myArray.unshift(6); // [6, 1, 3, 2]

Non-destructive versions:

const myArray = [1, 3, 2];
const newArray = [6, ...myArray];

Or (if you have access to toSpliced):

const myArray = [1, 3, 2];
const newArray = myArray.toSpliced(0, 0, 6);

Splice

Destructive version:

const myArray = [1, 3, 2];
myArray.splice(1, 1, 4, 5, 6); // [1, 4, 5, 6, 2]

Non-destructive versions:

const myArray = [1, 3, 2];
const newArray = [
  ...myArray.slice(0, 1),
  4, 5, 6,
  ...myArray.slice(2, myArray.length)
];

Or (if you have access to toSpliced):

const myArray = [1, 3, 2];
const newArray = myArray.toSpliced(1, 1, 4, 5, 6);

Reverse

Destructive version:

const myArray = [1, 3, 2];
myArray.reverse(); // [2, 3, 1]

Non-destructive versions:

const myArray = [1, 3, 2];
const newArray = [...myArray].reverse();

Or (if you have access to toReversed):

const myArray = [1, 3, 2];
const newArray = myArray.toReversed();

Sort

Destructive version:

const myArray = [1, 3, 2];
myArray.sort(); // [1, 2, 3]

Non-destructive versions:

const myArray = [1, 3, 2];
const newArray = [...myArray].sort();

Or (if you have access to toSorted):

const myArray = [1, 3, 2];
const newArray = myArray.toSorted();
@alveshelio
Copy link

alveshelio commented Jun 2, 2023

Hi @jherr,

Thank you very much for these precious nuggets 😄
These methods are in state 4, are they already available in Typescript? I was trying to use . toSorted but I'm getting an error toSorted is not a function

I was looking into my tsconfig file and I have "lib": ["DOM", "DOM.Iterable", "ESNext"], in my compilerOptions so I should be good no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment