JavaScript basicsArrays in plain wordsOne method at a time
Array
Toolbox
An array is a list of values in a row. Arrays come with built in tools for changing, searching, counting and sorting that list. This guide explains each one in plain words, with a small example you can run.
Key terms in plain words
Never written code before? Start here. Every word below turns up later on this page, each with an everyday comparison drawn from a row of numbered boxes on a storeroom shelf. Underlined words in the modules link back to these cards.
21 terms in 4 groups. Hover an underlined word anywhere on the page for a quick reminder, or click it to jump here.
What an array is
An array is a row of numbered boxes on a shelf. These are the words for the row, the boxes and what sits inside them.
- Array
- Think of it as a row of numbered boxes on one shelf
- A list of values kept in order. Each value sits in its own box, and the boxes are counted from zero along the row.
- For example
[30, 80, 10]is an array of three prices. - Item
- Think of it as whatever is sitting inside one box
- One value in the array. It can be a number, a piece of text, or something bigger such as a whole order with its own details.
- For example In
["apple", "mango"]the items are "apple" and "mango". - Position (index)
- Think of it as the number painted on the front of each box
- Where an item sits in the row. Counting starts at 0, so the first item is at position 0 and the third is at position 2. A method that finds nothing at all answers -1, a position that cannot exist.
- For example
fruits.at(0)gets the first item,fruits.at(-1)the last. - Length
- Think of it as counting how many boxes are on the shelf
- How many items the array holds. It is always one more than the last position, because counting starts at 0.
- For example
[4, 5, 6].lengthis 3. - Object
- Think of it as a box with labelled compartments inside it
- A bundle of named values, such as a fruit with a name, a price and a quantity. Arrays often hold a list of objects, one per order or person.
- For example
{ name: "apple", price: 30 }is one object. - String
- Think of it as a label written on a strip of paper
- A piece of text, written between quotes. Programmers call it a string because it is a string of letters in a row.
- For example
"mango"and"2026-09-28"are both strings.
Methods and helpers
Most tools on this page walk along the row for you. You hand them a small set of instructions to follow at every box.
- Method
- Think of it as a ready-made tool that comes clipped to the shelf
- A built-in action that belongs to the array. You call it by writing a dot and its name after the array, then brackets.
- For example
prices.map(...)calls the map method onprices. - Function
- Think of it as a written recipe card you can use again and again
- A named or unnamed set of steps. It takes some values in, does its work and can hand one value back.
- For example
(price) => price + 5is a tiny function that adds 5. - Callback
- Think of it as a note of instructions you leave for the stock clerk to follow at every box
- A function you pass to a method so the method can run it for you, once per item. This page calls it the helper. It usually receives the item and its position.
- For example In
prices.map((price) => price + 5)the helper is(price) => price + 5. - Return value
- Think of it as what the clerk hands back to you at the end
- The answer a method or helper gives back. Knowing what each method returns, a new array, one item, a number or nothing, is most of the skill on this page.
- For example
forEachreturns nothing;mapreturns a new array. - undefined
- Think of it as an empty box where you hoped to find something
- JavaScript's word for "no value here".
findgives it back when nothing matches, and reading past the end of an array gives it too. - For example
cart.find((item) => item.name === "kiwi")givesundefined. - True or false
- Think of it as a tick or a cross on a checklist
- The answer to a yes or no question. Programmers call these values booleans.
some,everyandincludesall give one back. - For example
[19, 24].every((age) => age >= 18)istrue.
Changing or copying
Some tools rearrange the boxes on the real shelf. Others build a second shelf and leave the first one alone.
- Mutate
- Think of it as moving the boxes around on the real shelf
- To change the array you already have, in place.
push,pop,splice,sortandreverseall do this, so anything else using that array sees the change too. - For example After
days.splice(1, 2)thedaysarray itself is shorter. - Copy
- Think of it as setting up a second shelf and leaving the first exactly as it was
- A new array built from the old one. Changing the copy leaves the original untouched, which avoids surprise bugs when the same list is used somewhere else.
- For example
days.slice(1, 3)copies two days and leavesdaysalone. - Original
- Think of it as the shelf you started with
- The array you called the method on. The newer "to" methods,
toSortedandtoReversed, exist so the original stays safe. - Nested array
- Think of it as boxes packed inside other boxes
- An array that holds other arrays as items. Flattening opens those inner boxes so every item sits in one plain row.
- For example
[1, [2, 3]].flat()gives[1, 2, 3]. - Spread syntax
- Think of it as tipping every box out onto a fresh shelf
- Three dots before an array,
...list, which lays its items out one by one inside something new. It is the usual way to copy or join arrays in modern code. - For example
[...a, ...b]joins two arrays into a new one.
Getting answers out
Turning a whole shelf into one total, a neat order, or a short report.
- Running total (accumulator)
- Think of it as a tally sheet you carry down the row, adding as you go
- The value
reducecarries from one item to the next. You give it a start value, the helper updates it at every box, and whatever is left after the last box is the answer. - For example In
prices.reduce((sum, price) => sum + price, 0)the running total issumand it starts at 0. - Compare helper
- Think of it as a rule for which of two boxes goes first
- A helper you give to
sortortoSorted. It looks at two items and answers with a number: below zero puts the first one earlier, above zero puts it later. Without one, sort treats numbers as text, so 100 lands before 5. - For example
(a, b) => a - bsorts numbers small to big. - Set
- Think of it as a shelf that refuses a second copy of any box
- A separate kind of list that keeps each value only once. Turning an array into a Set and back is the quickest way to remove repeats.
- For example
[...new Set([1, 1, 2])]gives[1, 2]. - Chaining
- Think of it as an assembly line where each worker passes the tray to the next
- Calling one method straight after another, because each one hands back a new array. Read a chain top to bottom like the steps of a recipe.
- For example
paid.toSorted(...).slice(0, 2).map(...)
Loop and change
Visit every item with forEach, or build a brand new array with map.
Think of an array as a row of boxes, each holding one value. Most array methods take a small helper function and call it once for every box, handing it the item and its position. What the method does with the helper's answer is what makes each method different.
Picture it: map
308010map(p => p + 5)358515Same number of boxes, every one changed.Runs your helper on every item. Use it when you only want to do something, like printing.
See the exampleRuns your helper on every item and collects each answer into a new array.
See the example// forEach: do something with every item. It gives nothing back.
const prices = [30, 80, 10];
prices.forEach((price, index) => console.log(`item ${index} costs ₹${price}`));
// map: build a NEW array by changing every item
const withDelivery = prices.map((price) => price + 5);
console.log(withDelivery);
console.log(prices); // the original stays the same
Easy way to remember: if you want an array back, use map. If you just want to do something, use forEach.
$ node foreach-map.js item 0 costs ₹30 item 1 costs ₹80 item 2 costs ₹10 [ 35, 85, 15 ] [ 30, 80, 10 ]
const cart = [
{ name: "apple", price: 30, qty: 4 },
{ name: "mango", price: 80, qty: 2 },
{ name: "banana", price: 10, qty: 12 },
];
// pull one field out of every object
const names = cart.map((item) => item.name);
console.log(names);
// turn every object into a label
const labels = cart.map((item) => `${item.qty} x ${item.name}`);
console.log(labels);
Common use: turning a list of objects into a list of names, labels or IDs is one map away.
$ node map-objects.js [ 'apple', 'mango', 'banana' ] [ '4 x apple', '2 x mango', '12 x banana' ]
Pick and search
Keep only the items you want with filter, or grab one item with find.
Picture it: filter
308010filter(p => p < 50)308010Keeps the boxes where the helper says yes.Keeps every item where your helper returns true.
See the exampleReturns the first item where your helper returns true.
See the exampleLike find, but gives the position instead of the item.
See the exampleLike find, but starts searching from the end.
See the exampleChecks if the exact value is in the array.
See the exampleTells you where the value first appears.
See the exampleGets the item at a position. Negative numbers count from the end.
See the exampleconst cart = [
{ name: "apple", price: 30 },
{ name: "mango", price: 80 },
{ name: "banana", price: 10 },
];
const cheap = cart.filter((item) => item.price < 50); // ALL that match
console.log(cheap.map((item) => item.name));
const mango = cart.find((item) => item.name === "mango"); // FIRST that matches
console.log(mango);
console.log(cart.findIndex((item) => item.name === "banana")); // its position
console.log(cart.find((item) => item.name === "kiwi")); // nothing found
Easy way to remember: filter gives you a list, even if it is empty. find gives you one thing, or undefined when nothing matches.
$ node filter-find.js [ 'apple', 'banana' ] { name: 'mango', price: 80 } 2 undefined
const fruits = ["apple", "mango", "banana", "mango"];
console.log(fruits.includes("mango")); // is it there at all?
console.log(fruits.indexOf("mango")); // first position
console.log(fruits.lastIndexOf("mango")); // last position
console.log(fruits.indexOf("kiwi")); // -1 means "not found"
console.log(fruits.at(0), fruits.at(-1)); // first item, last item
Tip: use includes for simple values like text and numbers. For objects, use find or some with a helper.
$ node includes.js true 1 3 -1 apple mango
Yes or no checks
Ask a question about the whole array and get back one true or false.
Picture it: some
19241731some(a => a < 18)trueOne yes is enough.True only if every single item passes your test.
See the exampleconst ages = [19, 24, 17, 31];
console.log(ages.some((age) => age < 18)); // is at least ONE under 18?
console.log(ages.every((age) => age >= 18)); // is EVERY one 18 or older?
// both stop early: some at the first yes, every at the first no
console.log([].some((n) => n > 0), [].every((n) => n > 0)); // empty array
Easy way to remember: some is "is there any?" and every is "are they all?". On an empty array some is false and every is true, because nothing failed.
$ node some-every.js true false false true
Boil it down
Squash a whole array into one value, like a total, a count or a winner, with reduce.
reduce feels hard at first, but it is just a loop that carries one value along. You give it a helper and a starting value. The helper receives the value so far and the current item, and returns the updated value. Whatever comes out after the last item is the answer.
Picture it: reduce
308010reduce((sum, p) => sum + p, 0)120Many boxes in, one value out.| Step | sum so far | current item | helper returns |
|---|---|---|---|
| Start | 0 | 30 | 0 + 30 = 30 |
| Second | 30 | 80 | 30 + 80 = 110 |
| Third | 110 | 10 | 110 + 10 = 120 |
const prices = [30, 80, 10];
// reduce(helper, startValue)
// the helper gets the running result and the current item,
// and returns the new running result
const total = prices.reduce((sum, price) => sum + price, 0);
console.log(total);
// the same thing written as a plain loop
let sum = 0;
for (const price of prices) sum = sum + price;
console.log(sum);
See the link: reduce is the plain loop on the bottom, folded into one line. The 0 at the end is where the sum starts.
$ node reduce.js 120 120
const cart = [
{ name: "apple", price: 30, qty: 4 },
{ name: "mango", price: 80, qty: 2 },
{ name: "banana", price: 10, qty: 12 },
];
// 1. the full bill
const bill = cart.reduce((sum, item) => sum + item.price * item.qty, 0);
console.log(bill);
// 2. count how often each vote appears
const votes = ["yes", "no", "yes", "yes", "maybe"];
const tally = votes.reduce((count, vote) => {
count[vote] = (count[vote] ?? 0) + 1;
return count;
}, {});
console.log(tally);
// 3. keep the most expensive item
const priciest = cart.reduce((best, item) => (item.price > best.price ? item : best));
console.log(priciest.name);
Always give a start value: without one, reduce uses the first item as the start, which works for picking a winner but throws an error on an empty array.
$ node reduce-more.js 400 { yes: 3, no: 1, maybe: 1 } mango
Add and remove
Put items in or take them out at the start, the end or the middle.
Removes the last item.
See the exampleAdds items to the start.
See the exampleRemoves the first item.
See the exampleCopies a piece of the array. The end position is left out.
See the exampleCuts items out of the real array and can put new ones in their place.
See the exampleconst queue = ["Asha", "Ravi"];
queue.push("Meera"); // add to the END
queue.unshift("Dev"); // add to the START
console.log(queue);
const last = queue.pop(); // remove from the END
const first = queue.shift(); // remove from the START
console.log(first, last);
console.log(queue);
Picture a queue: push and pop work at the back, unshift and shift work at the front.
$ node push-pop.js [ 'Dev', 'Asha', 'Ravi', 'Meera' ] Dev Meera [ 'Asha', 'Ravi' ]
const days = ["Mon", "Tue", "Wed", "Thu", "Fri"];
// slice(start, end): COPY a piece. The end index is not included.
console.log(days.slice(1, 3));
console.log(days.slice(-2)); // the last two
console.log(days); // untouched
// splice(start, howMany, ...newItems): CUT from the real array
const removed = days.splice(1, 2, "Holiday");
console.log(removed);
console.log(days); // changed!
The one letter trap: slice copies and leaves the array alone. splice changes the array. When unsure, slice is the safe one.
$ node slice-splice.js [ 'Tue', 'Wed' ] [ 'Thu', 'Fri' ] [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri' ] [ 'Tue', 'Wed' ] [ 'Mon', 'Holiday', 'Thu', 'Fri' ]
Put in order
Sort and reverse arrays, and learn the newer versions that keep your original safe.
Puts items in order, inside the original array.
See the exampleSame as sort, but returns a sorted copy.
See the exampleFlips the order, inside the original array.
See the exampleReturns a flipped copy.
See the exampleReturns a copy with one position replaced.
See the exampleconst nums = [10, 1, 5, 100];
// careful: without a helper, sort compares items as text
console.log([...nums].sort());
// (a, b) => a - b means small to big, b - a means big to small
console.log([...nums].sort((a, b) => a - b));
console.log(nums.toSorted((a, b) => b - a)); // new array, nums unchanged
console.log(nums);
const words = ["mango", "Apple", "banana"];
console.log(words.toSorted((a, b) => a.localeCompare(b)));
The number trap: plain sort treats numbers as text, so 100 comes before 5. Always pass (a, b) => a - b for numbers, and localeCompare for words.
$ node sort.js [ 1, 10, 100, 5 ] [ 1, 5, 10, 100 ] [ 100, 10, 5, 1 ] [ 10, 1, 5, 100 ] [ 'Apple', 'banana', 'mango' ]
const steps = ["wake", "brush", "breakfast"];
console.log(steps.toReversed()); // new, reversed copy
console.log(steps.with(1, "shower")); // new copy with one item swapped
console.log(steps); // still the same
steps.reverse(); // reverse changes the original
console.log(steps);
Why the "to" versions exist: they never change the array you already have, which avoids surprise bugs when the same array is used somewhere else.
$ node reverse.js [ 'breakfast', 'brush', 'wake' ] [ 'wake', 'shower', 'breakfast' ] [ 'wake', 'brush', 'breakfast' ] [ 'breakfast', 'brush', 'wake' ]
Reshape and create
Flatten nested arrays, join arrays into text and build new arrays from scratch.
Opens nested arrays so their items sit in one list.
See the exampleRuns map, then flattens one level.
See the exampleJoins arrays end to end.
See the exampleMakes an array from text, a Set or a length.
See the exampleSets every position to the same value.
See the exampleconst nested = [1, [2, 3], [4, [5]]];
console.log(nested.flat()); // open one level of boxes
console.log(nested.flat(Infinity)); // open every level
const lines = ["good morning", "see you soon"];
console.log(lines.flatMap((line) => line.split(" "))); // map, then flat
console.log(["2026", "09", "28"].join("-")); // array to text
console.log([1, 2].concat([3, 4], 5)); // glue arrays together
Tip: the spread syntax [...a, ...b] does the same job as concat and is what you will see most often in modern code.
$ node flat-join.js [ 1, 2, 3, 4, [ 5 ] ] [ 1, 2, 3, 4, 5 ] [ 'good', 'morning', 'see', 'you', 'soon' ] 2026-09-28 [ 1, 2, 3, 4, 5 ]
// make arrays from scratch
console.log(Array.from({ length: 5 }, (_, i) => i + 1)); // 1 to 5
console.log(new Array(3).fill("-")); // three dashes
console.log(Array.from("hey")); // text to letters
console.log(Array.from(new Set([1, 1, 2, 3, 3]))); // remove repeats
// check what you have
console.log(Array.isArray([1, 2]), Array.isArray("12"));
console.log([4, 5, 6].length);
Handy trick: Array.from(new Set(list)) is the shortest way to remove repeated values.
$ node create.js [ 1, 2, 3, 4, 5 ] [ '-', '-', '-' ] [ 'h', 'e', 'y' ] [ 1, 2, 3 ] true false 3
All together
Chain several methods to answer real questions about a list of orders.
Because map, filter, toSorted and slice all return new arrays, you can call the next method straight away. Read a chain top to bottom like a recipe. Each line takes the result of the line above.
const orders = [
{ customer: "Asha", items: ["apple", "mango"], total: 110, paid: true },
{ customer: "Ravi", items: ["banana"], total: 120, paid: false },
{ customer: "Meera", items: ["mango", "kiwi", "apple"], total: 260, paid: true },
{ customer: "Dev", items: ["kiwi"], total: 90, paid: true },
];
const paid = orders.filter((o) => o.paid); // keep paid ones
const revenue = paid.reduce((sum, o) => sum + o.total, 0); // add them up
const top2 = paid
.toSorted((a, b) => b.total - a.total) // biggest first
.slice(0, 2) // take two
.map((o) => o.customer); // just names
const fruits = [...new Set(orders.flatMap((o) => o.items))].sort(); // every fruit once
const anyUnpaid = orders.some((o) => !o.paid);
console.log("revenue:", revenue);
console.log("top customers:", top2);
console.log("fruits sold:", fruits.join(", "));
console.log("chase payments?", anyUnpaid);
Read the chain for top2: sort the paid orders biggest first, take the first two, then keep only the names. Each step is one simple method.
$ node orders.js revenue: 460 top customers: [ 'Meera', 'Asha' ] fruits sold: apple, banana, kiwi, mango chase payments? true
# save any example as a file and run it with Node 20 or newer $ node orders.js # or paste it into your browser console with F12
Which one do I need?
Start from what you want to do, then read across to the method and what it gives back.
| I want to | Use | You get |
|---|---|---|
| Change every item | map | a new array, same length |
| Keep some items | filter | a new, shorter array |
| Find one item | find | the item or undefined |
| Know if a value is there | includes | true or false |
| Check if any item passes | some | true or false |
| Check if all items pass | every | true or false |
| Get one total or summary | reduce | a single value |
| Just do something per item | forEach | nothing |
| Put items in order | toSorted | a sorted copy |
| Take a piece | slice | a copy of that piece |
| Turn the array into text | join | a string |