Updated June 2026. Tested on modern JavaScript (ES2020+). Part of the Techalyst JavaScript series.
Most of the work in a Vue app is shaping data before it hits the template. A list of products comes back from an API and you need the cheap ones, sorted by price, with the names pulled out. That is all array methods.
The ones worth knowing fall into two groups. Some return a new array and leave the original alone. Some change the array in place. In Vue that distinction is not academic, it decides whether your computed properties behave or quietly corrupt your state. That is the angle here. If you just want the plain JavaScript reference for these methods on their own, see Essential JavaScript Array Methods. Below we look at the same methods through one lens: how they sit with Vue's reactivity. First, the everyday methods.
map, filter and find
These three cover most of what you do day to day. map transforms every element and gives you a new array of the same length. filter keeps the elements that pass a test. find returns the first match, or undefined.
const products = [
{ id: 1, name: 'Keyboard', price: 80 },
{ id: 2, name: 'Monitor', price: 220 },
{ id: 3, name: 'Mouse', price: 40 },
];
const names = products.map(p => p.name); // ['Keyboard', 'Monitor', 'Mouse']
const cheap = products.filter(p => p.price < 100); // Keyboard and Mouse
const one = products.find(p => p.id === 2); // the Monitor object
find has a cousin, findIndex, that returns the position instead of the element, or -1 if nothing matches. It pairs well with splice when you want to remove a specific item:
const idx = products.findIndex(p => p.id === 3);
if (idx !== -1) products.splice(idx, 1);
None of map, filter or find touch the original array. That is exactly why they are safe to lean on.
some, every and includes
When you only need a yes or no answer, reach for these instead of looping. some is true if any element matches, every is true if all of them do, and includes checks for a plain value.
products.some(p => p.price > 200); // true, the Monitor
products.every(p => p.price > 10); // true, all of them
[1, 2, 3].includes(2); // true
These are clearer than writing a loop with a flag variable, and they stop early once the answer is settled.
reduce, without the fear
reduce scares people more than it should. It walks the array and carries a running value, the accumulator, from one element to the next. Whatever you return becomes the accumulator for the next round. The second argument is the starting value, and getting it right is most of the battle.
// Sum a property. Start at 0.
const total = products.reduce((sum, p) => sum + p.price, 0); // 340
// Count occurrences. Start with an empty object.
const cities = ['Tokyo', 'Paris', 'Tokyo', 'Tokyo', 'Paris'];
const counts = cities.reduce((result, city) => {
result[city] = (result[city] || 0) + 1;
return result;
}, {});
// { Tokyo: 3, Paris: 2 }
// Group a list by a property. Start with an empty object.
function groupBy(list, prop) {
return list.reduce((result, item) => {
const key = item[prop];
(result[key] ||= []).push(item);
return result;
}, {});
}
A simple guide for the starting value: use 0 when you are adding numbers, [] when you are collecting into a list, and {} when you are counting or grouping. Once you see it as "give me a starting box and I will fill it", reduce stops being mysterious.
The two things to know about sort
sort is where people get burned, for two reasons.
The first is that it mutates the original array. It does not hand you a sorted copy, it rearranges the one you gave it.
The second is that the comparator must return a number, not a boolean. Return a negative number to put a first, positive to put b first, zero to leave them be. Subtraction does this neatly for numbers:
products.sort((a, b) => a.price - b.price); // ascending by price
products.sort((a, b) => b.price - a.price); // descending
Returning true or false from a comparator works by accident in some browsers and not others, so always return a number.
Why this matters in Vue
Here is the part that turns a JavaScript habit into a Vue bug. A computed property should be a pure read of your state. It should never change the data it reads from. But sort mutates, so this is a trap:
// Wrong. sort() mutates this.products, which is your reactive state.
const sortedProducts = computed(() => {
return this.products.sort((a, b) => a.price - b.price);
});
Sorting reactive state inside a computed mutates the source, which can re-trigger the computed, which sorts again. Best case you get confusing behaviour, worst case an update loop. The fix is to copy first, then sort the copy:
const sortedProducts = computed(() => {
return [...products.value].sort((a, b) => a.price - b.price);
});
This is the real reason map, filter and reduce feel so natural in Vue. They return new arrays, so a computed built on them never disturbs the state underneath. The mutating methods, sort, splice, reverse and push, are fine when you genuinely mean to change state, but keep them out of computed properties.
Quick reference
| Method | Returns | Mutates the original |
|---|---|---|
map |
new array, same length | no |
filter |
new array, subset | no |
find / findIndex |
one element / index | no |
some / every |
boolean | no |
reduce |
whatever you build | no |
slice |
a copy of a portion | no |
sort / reverse |
the same array | yes |
splice / push / pop |
removed items / length | yes |
Wrapping up
You do not need every array method in your head. Know map, filter and find for the everyday work, reduce for anything that collapses a list into one value, and some and every for quick checks. Remember that sort mutates and needs a numeric comparator, and copy your state with the spread operator before sorting it in a computed. Get those few right and most of your data shaping in a Vue app writes itself.
All comments ()
No comments yet
Be the first to leave a comment on this post.