Search by title or category tag
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.
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
});
‘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:
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.
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.
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() 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(...)
}