Today I learned
Array Sort modifies the original array
JavaScript provides us a ton of useful array methods. One of them is the
.sort()
method, which as the name says sorts an array.
This is useful, if you want to sort a list in alphabetical order for example.
What I didn't knew about the .sort()
method was that it modifies the original
array! As the
mdn
docs ↗ put it:
The sort() method sorts the elements of an array in place and returns the reference to the same array, now sorted.
What does that mean? Let's see an example. Imagine you have a component that renders a list of items and also has a select to filter items. The select should be sorted alphabetically, but the list of items should not be sorted.
const items = [
{ name: 'Spaghetti aglia olio', kitchen: 'italian' },
{ name: 'Bami Goreng', kitchen: 'vietnamnese' },
{ name: 'Pad Thai', kitchen: 'thai' },
]
const FavoriteFood = ({ items }) => {
const sortedItems = items.sort((a, b) => {
if (a.kitchen < b.kitchen) return -1
if (a.kitchen > b.kitchen) return 1
return 0
})
return (
<>
<select>
{sortedItems.map((item) => (
<option key={item.name}>{item.name}</option>
))}
</select>
<section>
{items.map((item) => (
<article key={item.name}>
{item.kitchen} - {item.name}
</article>
))}
</section>
</>
)
}
What do you think happens here? Our intention is, to show the list of foods sorted alphabetically in the dropdown, but not sorted below. But that's not what is happening here:
As I said before, the sort()
method modifies the original array. This means
whenever you apply the sorting on the items array, the reference is also sorted.
That's why our list of items below the dropdown is also sorted.
To fix this, there is an easy solution. Create a copy of the array you want to sort and sort that copy.
Do ✅
const FavoriteFood = ({ items }) => {
const sortedItems = [...items].sort((a, b) => {
if (a.kitchen < b.kitchen) return -1
if (a.kitchen > b.kitchen) return 1
return 0
})
return (
<>
<select>
{sortedItems.map((item) => (
<option key={item.name}>{item.name}</option>
))}
</select>
<section>
{items.map((item) => (
<article key={item.name}>
{item.kitchen} - {item.name}
</article>
))}
</section>
</>
)
}
Here our items array is copied by using thespread operator
. This makes sure we
only have sorted items in our select, but not in our list below. Hope this helps
you, to prevent bugs in the future!
I hope you enjoyed this post and learned something new. If you have any questions, feel free to reach out to me via Email Opens in new tab.
If you want to support me, you can buy me a coffee. I would be very happy about it!
☕️ Buy me a coffee ☕️I wish you a wonderful day! Marco