loading...

Better loops in JavaScript

kartik2406 profile image Kartik Malik Updated on ・4 min read

Loops

In this post, we will take a look at forms of for loop, array methods using which you can make your code simpler, more readable. These loops / methods are useful when you want to manipulate data in an array or object.

for in loop

With this kind of loop you don't have to iterate over array indices, object keys manually.

//iterating over an array
let arr = [1, 2, 3, 4, 5]
for (let index in arr) {
  console.log(arr[index])
}
// Output: 1,2,3,4,5

//iterating over object keys
let obj = { id: 1, msg: 'hello' }
for (let key in obj) {
  console.log(obj[key])
}
// Output: 1, hello

for of loop

Using this loop you can get the value at a particular index. This loop only works on arrays.

for (let val of arr) {
  console.log(val)
}
// Output: 1,2,3,4,5

Array methods

Now let's take a look at a few array loop methods. When processing arrays the loops tend to become too large, we have to explicitly push items into another array and so on. The following methods make it easier to deal with such scenarios. The following methods take a callback function as an argument that will be executed for each element in the array. Let's look at a few examples.

Iterating over an array

For this, you can use the array.forEach() method. For-each takes a callback as an argument and executes it for each array element.

// display index and value
arr.forEach((value, index) => console.log(`Index = ${index} Value = ${value}`))

Transforming an array

To transform an existing array into another form you can use array.map() method. The map() method takes a callback as an arguement and returns a new array. The elements in the new array will be values that were returned by the callback.

Let's say you have an array of objects, each object has id, name. You want an array that contains just the ids.

with for loop

let data = [
  { id: 1, name: 'Phone', type: 'electronic' },
  { id: 2, name: 'Laptop', type: 'electronic' },
  { id: 3, name: 'Shirt', type: 'clothing' },
]
let ids = []
for (let i = 0; i < data.length; i++) {
  ids.push(data[i].id)
}

with map

let ids = data.map(function(val) {
  return val.id
})

or even shorter and simpler with an arrow function

let ids = data.map(val => val.id)

Filtering elements from the array

To filter elements from the array you can make use of array.filter() method. The filter() method expects a callback, this callback will be executed for each element in the array & returns a new array that contains filtered items. If the callback function returns true for a given element that element will be in the filtered array.

Selecting electronic items

let electronics = data.filter(item => item.type == 'electronic')

Searching for an element in the array

If you want to search for an element in the array you can use array.find() method. Like all the other methods discussed here, this method also requires a callback. The callback function should return true or false. The the first value for which the callback returns true will be the output of this method. If there is no match, the function will return undefined.

Searching for name 'Phone'

data.find(val => val.name == 'Phone')

Getting a single value from an array

To obtain a single value from an array you can use the array.reduce() method. The reduce() method, takes a callback function, initial value as an argument. The callback intern has an accumulator, currentValue as mandatory arguments. Accumulator contains the value that was obtained from the previous execution of the callback, currentValue is the array element under processing.

Sum and product of the array

let arr = [1, 2, 3, 4, 5]

//sum of array elements
arr.reduce((accumulator, currentValue) => (accumulator + currentValue), 0)
// where 0 is the initial value
// Output: 15

// product of array elements
arr.reduce((accumulator, currentValue) => (acc * currentValue), 1)
// Output: 120

Checking if a condition is true for at least one element in the array.

For this use array.some() method. This method will return true if the condition is true on at least one element in the array, otherwise it will return false.

let friends = [13, 15, 16, 18] //ages of group of friends

// checking if at least one of them is 18 or above
friends.some(val => val >= 18)

Checking if a condition is true for all the elements in the array

For this use array.every() method. This method will return true if a condition is true for all the elements in the array, otherwise it will return false.

let giftPrices = [300, 350, 399, 400]
let budgetPerGift = 450

let checkBudget = price => price <= budgetPerGift

giftPrices.every(checkBudget) // true

budgetPerGift = 300

giftPrices.every(checkBudget) // false

Things to take care of

  • The array methods are slightly slower than normal for loop, but they offer a lot of advantages, and their performance will improve with changes to JS engines.
  • All the methods that we have discussed above (except some(), find()), execute on the entire array. If you don't want to do this than these methods are of no use to you. You can't use break to stop the callback.

That's it for today. These methods have lot's of potential, go through their documentation on MDN, try these out.

If you like this post do share it :).

Discussion

pic
Editor guide
Collapse
joelnet profile image
JavaScript Joel

Great article! I noticed some minor bugs:

// This:
arr.reduce((accumulator, currentValue) => (acc += curr), 0)

// Should be:
arr.reduce((acc, curr) => (acc + curr), 0)

You can change += to just be + also.

Same goes for:

// This:
arr.reduce((acc, curr) => (acc *= curr), 1)

// Can be:
arr.reduce((acc, curr) => (acc * curr), 1)

Cheers!

Collapse
kartik2406 profile image
Kartik Malik Author

Good catch :D thank you very much :)

Collapse
nielsbom profile image
Niels Bom

Nice article!

If people are interested to read more on this style of programming in JS, it's called "functional programming". See this article for an introduction: dev.to/leandrotk_/functional-progr...

A really nice library for doing functional-style programming with JS: ramdajs

Collapse
asparallel profile image
AsParallel

Some notes:

Beyond the 1:1, x can be represented as y comparison, it's important to note the behavior that occurs as well.

The important concept and takeaway here is we should as developers prefer the collection interface methods to imperative looping structures. Concepts this topic should lead into:

  • lazy execution
  • loop "merging"
  • declarative composition
  • monadic execution
  • guaranteed sequence of execution that avoids side effects and strongly conveys intent

Extra reading material:
“Stop Writing for-loops (lazy evaluation)” by William Carroll link.medium.com/f5fDWslBHS

Collapse
kartik2406 profile image
Kartik Malik Author

Thanks for the link it's a nice read to get into performant code :).

Collapse
hamedqaderi profile image
Hamm 🐘

Nice article. Thanks, Kartik. By the way, there is a little note to mention. It's better to use (for in) for objects and (for of) for arrays. Because (for in) has been optimized for Objects and not arrays.

Collapse
kartik2406 profile image
Kartik Malik Author

Oh cool, I didn't know that. Thanks for sharing :)

Collapse
juanmamenendez15 profile image
Juan Manuel Menendez Hernandez

// checking if at least one of them is 18 or above
arr.some(val => val >= 18)

should be:

// checking if at least one of them is 18 or above
friends.some(val => val >= 18)

Good article, but next time you need to check the examples in the console men, you can do it better ;)

Collapse
kartik2406 profile image
Kartik Malik Author

Hehe thanks. Did run the examples on console, changed the names later though hence the issue. Will be careful next time :)

Collapse
justintime4tea profile image
Justin Gross

Awesome write up! I'm glad you mentioned the less known ones as well like some and every. An additional note on the "for of" and forEach regarding accessing the index of an element would be nice. If you're interested in continuing to write about working with Arrays, the spread, rest, destructuring, Array.from and using asynchronous calls within loops would be another welcome write up!

Collapse
kartik2406 profile image
Kartik Malik Author

Yes these are interesting ideas will write about them soon :).

Collapse
summerkiflain profile image
Summer Kiflain

Nice article.

//sum of array elements
arr.reduce((accumulator, currentValue) => (acc += curr), 0)

should be:

//sum of array elements
arr.reduce((accumulator, currentValue) => (accumulator += currentValue), 0)

Collapse
kartik2406 profile image
Kartik Malik Author

Changed it. Thank you :)

Collapse
weirdmayo profile image
Daniel Mayovsky

I should have known about array.every() earlier than today. Would've saved me time and brains