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.
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 if at least one item passes your test.
See the exampleTrue 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.
Adds items to the end.
See the exampleRemoves 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 exampleGlues all items into one piece of text.
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 |