lukedavies.dev

Search by title or category tag

New Array methods in es2023

Luke Davies

TILjs

12/05/2023

I get pretty excited when we’re given new methods to work with and theres a few handy new array functions released in the latest es2023 proposals I’d like to talk about here. Firstly

findLast()

You can check MDN and see that findLast() is compatible across all browsers.

.findLast() MDN compatibility chart
.findLast() MDN compatibility chart

If you’re using the find method, each item is iterated over till the condition is met. Take this example:

const numbers = [42, 57, 1, 55, 86];

console.log("find:");

const findResult = numbers.find((value)=>{
  console.log('checking', value);
  return value === 86
});
console.log output
console.log output

‘checking: {value}’ is being console logged out for each item in the array moving from left to right.

Using the findLast() method we start from the end of the array, reducing the iterations needed.

const numbers = [42, 57, 1, 55, 86];

console.log("find:");

const findResult = numbers.findLast((value)=>{
  console.log('checking', value);
  return value === 86
});

In our console we can see:

console.log output
console.log output

There is also a findLastIndex() method which works in the same way but return the index.


Change array by copy

Now to the juicy part: Change array by copy which gives us 4 new methods to play with.

The four new methods we have are:

  • Array.prototype.toReversed() -> Array
  • Array.prototype.toSorted(compareFn) -> Array
  • Array.prototype.toSpliced(start, deleteCount, ...items) -> Array
  • Array.prototype.with(index, value) -> Array

Each one of these returns an updated copy of the array, and doesn't affect the original array.


toReversed()

You can check MDN and see that toReversed() is compatible across most browsers. Firefox being the exception.

toRevered() MDN compatibility chart
toRevered() MDN compatibility chart

If we use the reverse() method it will update the original array which in some cases we don’t want. Whereas the new toReverse() method will create a copy of the array and then reverse it. An coding example below

const numbers = [1, 2, 3, 4, 5];
const reversed = numbers.toReversed();

console.log(numbers);
console.log(reversed);

💡

This means we don’t have to use the [...] spread operator syntax

const numbers = [1, 2, 3, 4, 5];
const reversed = [...numbers].reversed();

console.log(numbers);
console.log(reversed);


toSorted()

You can check MDN and see that toSorted() is compatible across most browsers. Firefox being the exception.

toSorted() MDN compatibility chart
toSorted() MDN compatibility chart

Using .sort() modifies the original array, so if we needed a new sorted copy of the array, without modifying the original, we could use .toSorted()

const values = [43, 66, 102, 21, 7];
const sortNumbers = (a, b)=> a - b;
const sortedNumbers = values.toSorted(sortNumbers)

console.log(sortNumbers);
console.log(values);


toSpliced()

You can check MDN and see that toSpliced() is compatible across most browsers. Firefox being the exception.

toSpliced() MDN compatibility chart
toSpliced() MDN compatibility chart

toSpliced() is better explained in context of a small React todo app. In this app we can add and delete todo’s using useState.

Previously when adding or removing an item to the state we would have to create a copy of the array, modify it and then set that new modified copy as the state.

import {useState} from 'React'

const App = () => {
  const [todos, setTodos] = useState([]);
  ...
  const removeTodo = (index) => {
    setTodos((prev)=>[...prev].splice(index, 1))
  }
  ...
  return(...)
}

With toSpliced() a new array is returned so we can splice prev directly.

import {useState} from 'React'

const App = () => {
  const [todos, setTodos] = useState([]);
  ...
  const removeTodo = (index) => {
    setTodos((prev)=>prev.toSpliced(index, 1))
  }
  ...
  return(...)
}


with()

The with() method creates a copy of the array and uses the passed index to update an item of the array.

with() is compatible across most browsers. Firefox being the exception.

Using the React context again, this example shows updating one object in the state array’s value using its index.

import {useState} from 'React'

const App = () => {
  const [todos, setTodos] = useState([]);
  ...
  const updateTodo = (index) => {
    setTodos((prev)=>prev.with(index, {  ...prev[index],  done: !prev[index].done
    }))
  }
  ...
  return(...)
}

Previously, we would use map() to map over the state array and updating the item if its mapped index matches the passed in index.

import {useState} from 'React'

const App = () => {
  const [todos, setTodos] = useState([]);
  ...
  const updateTodo = (index) => {
    setTodos((prev) => prev.map((item, itemIndex)=>{  if(itemIndex === index){    return{      ...item,        done:!item.done    }  }  return item
    }))
  }
  ...
  return(...)
}

lukedavies.dev 2023