Javascript - Into The Loop of Arrays
Tags: beginners, javascript, webdev
Published: 2021-09-25 22:20:32

Salam and yosh!
And this week, I want to talk something core about Javascript. Something that you cannot escape, always bothering at the end of your thought when coding, avoiding them is not an option. And that is data structures. Yes, the basics of data structures, but we focus on one thing - [array].

You will always deal with arrays. Sooner or later, it will haunt your mind. What method should I use? How to manage arrays? How does array works?

In the Javascript world, an array is actually an object, with the ability to loop within the array items, since the index is arranged accordingly, so the loop will go through the index sequence. Starting from 0. Wait, starts from 0?

---

## Array

An object, with `number` as an index. Note that it is how the array works in Javascript, and not entirely applicable to other languages such as Python and others.

With a number as an index, it is possible to follow the sequence, starting from 0. As bit starts with 0, that is why the array starts with 0 and not 1. Because the index is arranged in sequence, it is possible to loop every element inside an array.

There are a lot of methods that can be used to loop through an array, with each of them serving a specific purpose, whether it modifies the array directly, or returning a new array or a value.

---

## The Normal Loop

Of course, Javascript has loops as other languages have, and they are `for`, `while` and `do...while`.

```javascript
for(let i = 0; i < 10; i++) {
  // This loop will execute 10 times
}

let j = 0;
while (j < 10) {
  // Same here
  j++;
}

let k = 0;
do {
  // Just the same, except the checking happens
  // after execution, opposite to `for` and `while` loop
  k++;
} while(k < 0);
```

Of course, there's nothing wrong with the usual loop method. Well, wait until you deal with the array. But here's a good thing about array. Every array has its own length by accessing `array.length`. Why not use this information for the loop?

---

## `for` For Array

For the first step, there is a `for` loop that is specifically for array, and that is `for...of`.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

for(let fruit of fruits) {
  console.log(fruit);
}

/* The output should be:

Durian
Rambutan
Nangka

*/
```

Not to be confused, that there is actually a similar loop to this, which is `for...in` which actually meant for an object instead and not array (yes, I know array also objects in Javascript, but that how it works!).

```javascript
const user = { fname: "Atif", lname: "Aiman", nname: "al-Serembani" };

for(let key in user) {
  console.log(user[key]);
}

/* The output should be:

Atif
Aiman
al-Serembani

*/
```

---

## For a Better Loop - Array Methods!

Well, it is cool that we have `for...of` to loop through an array, but there is a cooler way to loop through, and that is using array methods! There are tons, but with their own purposes. They are:

- `forEach`
- `map`
- `reduce` and `reduceRight`
- `filter`
- `find` and `findIndex`
- `some` and `every`
- `sort`
- `flatMap`

Since they are methods, the usage is not like the pattern we used before, but chained with the array itself.

Let's learn about them one by one, shall we?

---

## [`array.forEach`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)

`forEach` is just like our typical `for...of` loop. It **does not return anything**, and **didn't change the existing array**.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

fruits.forEach((fruit) => {
  console.log(fruit);
}

/* The output should be:

Durian
Rambutan
Nangka

*/
```

To explain a bit (will behave similarly across array methods later on), we loop through `fruits` array using `forEach`, and we pass `fruit` for the pointer that holds the element for each array element. From there, you can do anything to each element.

Since `forEach` didn't return any value, that means the example below doesn't work.

```javascript
const result = fruits.forEach((fruit) => { return fruit + ' juice' });

console.log(result); // undefined
```

And `forEach` didn't modify the existing array. This means the value will still same.

---

## [`array.map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)

![Array Map in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iujtds7eged1zz8kyry6.png)

`array.map` will go through the array, and then **return the same length of array with modified content**. It **doesn't modify the original array** though.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const juices = fruits.map((fruit) => {
  fruit.press();
});

console.log(juices);
// ['Durian juice', 'Rambutan juice', 'Nangka juice'];
```

As you noticed, I want to turn these fruits into juices, so I press every fruit and later I get the array of juices in return. Well, durian juice is indeed weird, but would you dare to try?

---

## [`array.reduce`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce) and [`array.reduceRight`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight)

![Array Reduce in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8zf5hux1p9r16tmjzc6z.png)

`array.reduce` will go through the array, and process everything, in **return of a single value**. Different with `array.map` that return the same length of the array of the target array. And still, not changing the original array.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const salad = fruits.reduce((product, fruit) => {
  return product + fruit.slice();
});

console.log(salad);
// DuRamNa Salad;
```

What I did here, I slice every fruit there is, and mixed with the product as it accumulates, and finally, the sliced fruits will be mixed together as a salad. Durian inside salad? Think again!

So, where do you usually see `reduce` in action? A really basic real-world example will be sum!


```javascript
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const sum = numbers.reduce((total, number) => {
  return total + number;
});

console.log(sum); // 55
```

So, what if you want to do the reverse way? Instead of starting from 0, do you want to start from the last element? For that case, we use `array.reduceRight`! The same way of writing, except it, will start from the last index of the array.

---

## [`array.filter`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

![Array Filter in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovn2v62ny6k1e9oo3lir.png)

`array.filter` will loop through the array, and filter **only when it matches the condition, or if it returns true**. The returned array will be **based on the filtered result**, and it didn't change the original value.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const bigFruits = fruits.filter((fruit) => {
  return fruit.isBig();
});

console.log(bigFruits); // ['Durian', 'Nangka']
```

I want to know which one is the big fruit. So I check the size of each fruit, and I get an array of big fruit in return. And now I know which one is big, and of course, Durian, king of fruits is one of them!

---

## [`array.find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) and [`array.findIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)

![Array Find in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bgy2u6sb12vzqfqleja.png)

`array.find` will loop through the array, and **only return one value which is the first occurrence that matches the condition**. Unlike `array.filter` which return all that matches the condition.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const bigFruit = fruits.find((fruit) => {
  return fruit.isBig();
});

console.log(bigFruit); // Durian
```

Durian is the first fruit in the array that is big. If durian doesn’t exist, nangka will be the next in line for the big fruit.

So, what if I don't want to know what fruit is big, instead I want to know the position inside the array? Then, `array.findIndex` will be a suitable method for you!

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const bigFruit = fruits.findIndex((fruit) => {
  return fruit.isBig();
});

console.log(bigFruit); // 0
```

So, what if we cannot find anything in an array that matches the condition? Then, it will return `undefined` for `array.find`, and `-1` for `array.findIndex`!

---

## [`array.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) and [`array.every`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every)

![Array Some and Every in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/stxlgyiynlajw0dhxnrt.png)

`array.some` and `array.every` will loop through the array, and check whether it matches the condition. While this is also achievable using `array.reduce` that returns a single value, `array.some` will return true if any of the element matches the condition, while `array.every` will return true if all elements match the condition. Both will return a boolean at the end of the day.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const hasSmallFruit = fruits.some((fruit) => {
  return fruit.isSmall();
});

console.log(hasSmallFruit); // true

const everthingBig = fruits.every((fruit) => {
  return fruit.isBig();
});

console.log(everythingBig); // false
```

I want to check if any of the fruit is small. Since rambutan is small, it will return true. And later on, I want to check if everything is big. Well, I might need a truck if everything is big!

---

## [`array.sort`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)

![Array Sort in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yg57lgth0azwyae6tej.png)

`array.sort` will loop through the array, and sort based on the condition. And of course, the return array will be at the same length, with the modified arrangement.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const sortedFruit = fruits.sort((fruitA, fruitB) => {
  if (fruitA > fruitB) return 1;
  else if (fruitA < fruitB) return -1;
  else return 0;
});

console.log(sortedFruit); // ['Nangka', 'Durian', 'Rambutan']
```

Here, I want to sort fruits based on their size. During the loop, it will take 2 parameters, the first fruit `fruitA` and the second fruit `fruitB`. It can be any first and any second, it will be managed by the sort function. Later, I compare them head-on to see which is the biggest of all fruits in this land.

If it returns a positive number, it will put the first fruit in front.
If it returns a negative number, it will put the first fruit at the back.
If it returns 0, it will just put as it is, since rearrange them doesn't matter, anyway.

As a result, now I know, even durian is the king of fruits, there is still bigger fruit which is nangka, so durian shouldn't feel too superior though.

So, how about making reverse sort? Just change from positive return to negative return, and that's it! You will get reverse sort!

Another thing. Is there a default sort method, so I don't have to pass a function to sort it? Of course, you can! They will be sorted based on lexigraphical order in character. In the other word, a-z will come out first then A-Z will follow later. Same applied to the numbers, where all will be treated as if they are string. Sorting `[1, 2, 5, 10, 15, 20, 50]` will result to `[1, 10, 15, 2, 20, 5, 50]`.

```javascript
const fruits = ['Durian', 'Rambutan', 'Nangka'];

const sortedFruit = fruits.sort();

console.log(sortedFruit); // ['Durian', 'Nangka', 'Rambutan']
```

---

## [`array.flatMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap)

![Array Flat Map in Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mojn2ql6b0826a2onq7x.png)

Well, it actually work the same way with `array.map` before, except that we are dealing with nested arrays.

Actually, there is one array method called `array.flat`, where it changes from the nested array (or non-single dimension array) and flat everything to only single dimension array. It is not a loop method, so that's why I didn't list it down.

Combining the power of `array.flat` and `array.map`, the result is `array.flatMap`, where it returns a new length of the flattened array.

---

## That's About It!

![All Array Loop Methods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ripy5gailkyqkkcsbqfa.png)

These are array methods you can use inside Javascript. It matches the ES2020 syntax, so you are welcome to use it.

Note that **all of the loop array methods didn't modify the original array**, so you don't have to worry. It will return a new value to their respective return method.

Awesome, now you know basic things about array loop methods! Well, only if the data structure is simple that is! What if you are dealing with a nested array or objects inside arrays? Only practice will reveal everything for you. Still, you still need to use these methods. How complex can you make your loop?

Okay guys! That's it for this week, and stay tuned! Until next time, peace be upon ya!