Skip to content
Topic 11 of 16
Theory

Array methods

Why it matters

In the previous topic we went through arrays with loops. It works, but the code gets long: create an empty array, a loop, a condition, push… Arrays have methods that do typical things in one line: "transform each element", "keep only the matching ones", "compute the total". Such code is shorter, easier to read, and that's how JavaScript is written in real projects.

All these methods take a callback — a function called for each element. Usually it's an arrow function from topic 8.

forEach — do something with each

const names = ["Anna", "Timur", "Ira"];
names.forEach((name, index) => {
  console.log(`${index + 1}. ${name}`);
});

Output:

1. Anna
2. Timur
3. Ira

The callback receives the element, its index and the array itself. forEach returns nothing — it's just a replacement for for.

map — transform each

map creates a new array of the same length from the callback's results:

const prices = [100, 250, 40];
const withTax = prices.map((p) => p * 1.2);
const labels = prices.map((p) => `${p} som`);
console.log(withTax);
console.log(labels);
console.log(prices);

Output:

[120,300,48]
["100 som","250 som","40 som"]
[100,250,40]

The original array doesn't change.

filter — keep the matching ones

filter returns a new array of only those elements for which the callback returned true:

const nums = [5, 12, 8, 130, 44];
console.log(nums.filter((n) => n > 10));
console.log(nums.filter((n) => n % 2 === 0));

Output:

[12,130,44]
[12,8,130,44]

find and findIndex — find the first

const users = [
  { name: "Anna", age: 15 },
  { name: "Timur", age: 19 },
  { name: "Ira", age: 21 },
];
console.log(users.find((u) => u.age >= 18));
console.log(users.findIndex((u) => u.age >= 18));
console.log(users.find((u) => u.age > 100));

Output:

{"name":"Timur","age":19}
1
undefined

(We'll cover objects like { name: …, age: … } in detail in the next topic. For now it's enough to know that u.age is the value of the age field.)

some and every — checking

const ages = [15, 19, 21];
console.log(ages.some((a) => a < 18));   // true  — at least one
console.log(ages.every((a) => a >= 18)); // false — all of them

reduce — fold into one value

reduce goes through the array and accumulates a result: a sum, a maximum, a string, an object.

const cart = [300, 150, 50];
const total = cart.reduce((sum, price) => sum + price, 0);
console.log(total);

Output:

500

The callback receives the "accumulator" (sum) and the current element and returns the new value of the accumulator. The second argument of reduce (0) is the accumulator's starting value. Step by step: 0 + 300 = 300 → 300 + 150 = 450 → 450 + 50 = 500.

sort — sorting

const words = ["cherry", "apple", "banana"];
words.sort();
console.log(words);

const nums = [10, 9, 100, 1];
nums.sort();
console.log(nums);              // surprise!
nums.sort((a, b) => a - b);
console.log(nums);

Output:

["apple","banana","cherry"]
[1,10,100,9]
[1,9,10,100]

Without a callback sort compares elements as strings, so "100" ends up before "9". For numbers always pass a compare function: (a, b) => a - b — ascending, (a, b) => b - a — descending. Important: sort (like reverse) changes the original array. To keep it, sort a copy: [...arr].sort(…).

Chains

Methods that return an array can be chained:

const orders = [120, 45, 300, 80, 15];
const bigTotal = orders
  .filter((x) => x >= 50)
  .map((x) => x * 0.9)
  .reduce((s, x) => s + x, 0);
console.log(bigTotal);

Output:

450

It reads like a sentence: "take the orders of 50 and up, apply a 10% discount, add them up".

How it works inside

Inside, each method is an ordinary loop. map could be written like this:

function myMap(arr, fn) {
  const result = [];
  for (let i = 0; i < arr.length; i++) result.push(fn(arr[i], i, arr));
  return result;
}

So methods aren't faster than loops — they're shorter and clearer. And sort with a callback asks at each step: "a and b — who goes first?". A negative answer means a first, positive — b first, zero — equal.

Common mistakes

  1. No return in a callback with curly braces. arr.map((x) => { x * 2 }) gives an array of undefined.
  2. forEach instead of map. forEach always returns undefined — it doesn't create a new array.
  3. Sorting numbers without a function. [10, 9, 1].sort() → [1, 10, 9]. You need sort((a, b) => a - b).
  4. sort spoiled the original array. Sort a copy: [...arr].sort(…).
  5. reduce without a starting value. On an empty array it throws. Always pass the second argument.

Cheat sheet

Method What it does Returns
forEach(fn) calls fn for each undefined
map(fn) transforms each a new array of the same length
filter(fn) keeps where fn → true a new array
find(fn) / findIndex(fn) the first match element / index (or undefined / -1)
some(fn) / every(fn) at least one / all true / false
reduce(fn, start) folds into one the final value
sort((a, b) => a - b) sorts in place the same array

Double everything

Easy+10 XP

Write a function doubleAll(numbers) that returns a new array where every number is multiplied by 2. Use the map method. The original array doesn't change.

doubleAll([1, 2, 3])  → [2, 4, 6]

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.