JavaScript - Loops

We sometimes have structures that call for looping across them. What we mean is that we want to examine each and every component of that construct and take action on it. Here are some examples of application areas:

  • Display every item: To graphically display each item in a list is a very typical use. On an e-commerce site, a typical example is to display every item in the cart so that you can see what you are about to buy. You may display everything in a list using a variety of loop constructions, including for, for/in, and for/of, to name a few. Further down on the page, you will discover more about how they are different.
  • Map: Iteratively changing a structure from one form to another is what mapping implies. When the data you have isn't quite ready for the following step, you usually want to do this. When it comes time to show your data, you might wish to switch from a data object to something more aesthetically pleasing.
  • Reduce: You go from one kind of data to a reduced one when you decrease it. What does that imply, then? It entails condensing a list of order items into something more interesting, like the sum of the individual components, for example.

Iterate items

You have a wide range of constructs at your disposal for iterating things. Start off with a simple for-loop. It is made in the following way:

for(<start condition>; <break condition>; <incremental phase> ) {
    // code block
}

The idea is to define a loop as having the following stages:

  • Start condition: You set the loop's starting value in the start condition, for instance by letting i=0;.
  • Break condition: You then specify a break condition, such as i<5, which, if met, causes the loop to cease iterating.
  • Increment phase: Finally, you specify how much the loop variable should rise or fall with each iteration.

A typical for-loop can look like so:

for (let i =0; i < 5; i++) {
    // code block
}

The variable i which represents the current location in the loop, is frequently used. It's preferable to give it a name that is more descriptive, such as:

for (let position =0; position < cart.length; position++) {
    // code block
}

NOTE: By using let to ensure that we have block scope, position will no longer exist once the loop has finished. Block scope and leaks outside the loop WILL NOT be provided via var.

// DON'T
for (var position =0; position < cart.length; position++) {
    // code block
}
// position is still alive here

For-in

One of the most perplexing loops is for-in. Use for-of instead has come up frequently in chats, but I've never heard anyone explain why. So let's describe the situation.

For-in lists the object's attributes. Let's demonstrate what the code below means:

let object = {
  name: 'Chris',
  city: 'London'
};

for (let prop in object) {
  console.log(prop)
}

// name, city

When you believe you may apply it on an array that resembles this, a problem arises:

let array = [1, 2, 3];

for (let prop in array) {
  console.log(prop)

// '0', '1', '2'

You receive the indices rather than the values for the area. If this surprises you, you should realize that JavaScript treats most things as objects. Consider the below code:

typeof [1,2,3] // 'object'

You are informed that you are working with an object by it. That implies that your array looks like this internally:

{
  "0": 1,
  "1": 2,
  "2": 3
}

Additionally, the method Object.keys() performs equivalent operations on the array. The output of the following code is comparable to that of for-in:

Object.keys([1,2,3]) // ['0', '1', '2']

NOTE: for-in and Object.keys() both act on keys/attributes and have a similar scope of application.

Getting the value

If it is values that you seek, you have several options:

Object.values([1,2,3]) // 1, 2, 3

You may also use the for-of loop as follows:

for(let obj of arr) {
  console.log(obj);
}

// 1,2,3

Alternatively, you can use forEach(), an array method, as follows:

let arr = [1,2,3];

arr.forEach((item, number, array) => console.log(item))

NOTE: You cannot use a break statement to end a forEach repetition (). Consider utilizing a normal for construct if you need to break a loop.

Changing the data

So far, you've only looked at ways to iterate over all the data, but you haven't altered anything. While iterating through the data, you can make changes to it. There are two constructs for changing data depending on how you want to change it: map() and reduce().

Map

map() is an array data structure function. The objective is to loop through all the entries in an array and replace each one with something new. It's possible that you're just interested in particular properties of an item, or that you wish to switch from a data model to something more visually appealing, such as a view model.

Let's look at an example:

let heroes = [{
  name: 'Xena',
  country: 'Greece'
}, {
  name: 'Alexander the Great',
  country: 'Macedonia'
}]

let onlyTheName = heroes.map(hero => {
  return hero.name;
});

// can also be written as: let onlyTheName = heroes.map(hero => hero.name)

onlyTheName.forEach(name => console.log(name)) // ['Xena', 'Alexander the Great']

You can see an example of iterating through an array and extracting the attribute name of interest above.

Reduce

reduce(), like map(), operates on the array data structure. It similarly aims to transform everything, but there is a key distinction. reduce() is concerned with executing an operation on the item and adding the result to a prior result from a previous iteration. This makes reduce() a suitable option to employ if you want to retrieve the sum of all cart items, for example, or if you want to merge a collection of objects into one. Consider the following examples:

let arr = [1,2,3,4];
let sum = arr.reduce((prev, curr) => prev + curr, 0)
// sum: 10

A callback is supplied above the reduce() method, with prev as the previous result and curr as the current item in the array. The callback eventually returns prev + curr. The second input to reduce() is a starting point. The total of all the values adds up to 10. Consider the following second example to demonstrate how powerful reduce() is:

let objects = [{
  name: 'Xena'
}, {
  country: 'Greece'
}]
let mergedObject = objects.reduce((prev, curr) => {
  return {
    ...prev,
    ...curr
  }
}, {})

// { name: 'Xena', country: 'Greece' }

Conclusion

I've demonstrated that there are numerous looping constructs available in JavaScript. They accomplish different things, and when used properly, they can make you pretty efficient. Even though for-of is definitely what you want, there's no reason to be afraid of using for-in now that you know what it does. If you haven't already, consider adding map() or reduce() to your toolbox.

I sincerely hope that the majority of you find the approach covered here to be helpful. Thank you for reading, and please feel free to leave any comments or questions in the comments section below.

Post a Comment

0 Comments