Section 3 · Working with Data
Arrays and Their Everyday Methods
18 min3 min readCode playground
Lesson at a glance
Create and change arrays, know which methods mutate them, and replace hand-written loops with map, filter, find, some and every to transform and search lists.
- 1Making and changing arrays
- 2map: transform every item
- 3filter: keep only some items
- 4find, some and every: searching
- 5Chaining: reading a pipeline
No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.
Pocket’s expenses are a list, and almost every feature is a question about that list. Which ones are refunds? What do they look like formatted as dollars? Is there anything over $100? You can answer all of these with the loops from section 2, but arrays come with methods that answer them in one readable line each.
Making and changing arrays
An array is an ordered list of values. You saw the basics already: square brackets, positions from 0, and length.
const amounts = [450, 1220, 270];
amounts.push(899); // add to the end
console.log(amounts);
const last = amounts.pop(); // remove from the end, and get it back
console.log(last, amounts);
amounts[0] = 500; // replace an item by index
console.log(amounts, amounts.includes(1220), amounts.indexOf(270));Wait: amounts is a const, yet it changed three times. That is not a contradiction. const means the name always points at the same array. It says nothing about what is inside the array. push, pop and index assignment all change the contents of that one array, so they are allowed. Only amounts = [...], pointing the name at a different array, would throw.
This idea, that a name points at a list and several operations change the list itself, is the reason to know which methods mutate:
| Changes the array | Returns something new, array untouched |
|---|---|
push, pop, shift, unshift |
slice, concat |
splice |
map, filter |
sort, reverse |
toSorted, toReversed |
Mutating is not wrong, but it surprises people when two parts of a program share one array. The methods in the rest of this lesson never mutate, which is a large part of why they are so popular.
The pair that confuses everyone is slice and splice, one letter apart and opposite in behaviour:
const amounts = [450, 1220, 270, 899];
const firstTwo = amounts.slice(0, 2); // copy of indexes 0 and 1
console.log(firstTwo, amounts); // original untouched
const removed = amounts.splice(1, 1); // remove 1 item at index 1
console.log(removed, amounts); // original changedslice(start, end) works exactly like the string method of the same name: it copies a piece and leaves the original alone. splice(start, count) cuts items out of the array itself and returns what it removed. If you ever need to remove an item without changing the original, use filter instead, which you are about to meet.
map: transform every item
map calls a function for each item and collects the return values into a new array of the same length:
const amounts = [450, 1220, 270];
const formatMoney = (cents) => `${(cents / 100).toFixed(2)}`;
const labels = amounts.map(formatMoney);
console.log(labels);
console.log(amounts); // unchangedIt is the built-in version of the applyToAll function you wrote in the functions lesson. Use map whenever the question is “turn each X into a Y”: cents into dollar strings, dollars into cents, raw form values into clean ones. The callback receives each item in turn and must return the new version of it. Whatever it returns lands at the same position in the result, so the output always has exactly as many items as the input.
filter: keep only some items
filter calls a test function for each item and returns a new array of only the items for which the test returned a truthy value:
const amounts = [450, -300, 1220, -50, 270];
const spending = amounts.filter((a) => a > 0);
const refunds = amounts.filter((a) => a < 0);
console.log(spending, refunds);The result can be shorter than the original, or even empty, but filter never changes the items themselves.
find, some and every: searching
Four methods answer search questions, and each stops as soon as it knows the answer:
const amounts = [450, 12000, 1220, 15000];
console.log(amounts.find((a) => a >= 10000)); // first match: 12000
console.log(amounts.findIndex((a) => a >= 10000)); // its position: 1
console.log(amounts.some((a) => a < 0)); // any refunds? false
console.log(amounts.every((a) => a > 0)); // all positive? truefind returns the item itself, or undefined if nothing matches. findIndex returns its position, or -1. some and every return booleans: “at least one” and “all of them”.
Chaining: reading a pipeline
Because filter and map both return arrays, you can call one on the result of the other:
const amounts = [450, -300, 12000, 1220];
const bigOnes = amounts
.filter((a) => a >= 1000)
.map((a) => `${(a / 100).toFixed(2)}`);
console.log(bigOnes);Read it top to bottom like a recipe: start with all amounts, keep the ones of $10 or more, format them. Each step gets the previous step’s output. Putting each step on its own line, starting with the dot, keeps long chains readable.
So far the arrays hold plain numbers. Real expenses have a label, an amount and a category together, which calls for objects, the subject of the next lesson.
Key takeaways
conststops a name from pointing at a different array, but the array’s contents can still change withpush,popor index assignment.- Some methods mutate the array (
push,pop,splice,sort); others return a new value and leave it untouched (slice,map,filter). mapreturns a new array of the same length with each item transformed;filterreturns a new array of only the items that pass a test.findreturns the first matching item orundefined;someandeveryanswer yes/no questions about the whole list.