DEV Community

Laura Berge
Laura Berge

Posted on

JS Array Methods: Filter, Map, Reduce, and Sort

When working with arrays in JavaScript, there are a number of methods at our disposal. I always think the best way to learn is to explore, so if you're unfamiliar or a beginner when it comes to array methods, be sure to type Array.prototype into the console in dev tools. A whole list of methods should print out beginning with contact and ending at values. Here are the docs with some more explanation of all the different methods. I'm just going to be explaining filter, map, reduce, and sort, but be sure to play around with any other methods you aren't familiar with.

For the following examples I am going to be using these arrays:

const numbers = [5, 2, -1, 3, 0, 2, 4, 2]
const alpha = ['d', 'w', 'a', 'v', 'y', 't', 'r', 'c', 'k']
const names = ['Zach', 'Laura', 'Matt', 'Jessica', 'Hannah']

Array.prototype.filter()

The filter function creates a new array from an existing array but removes any values that don't fit the passed in conditional. I'll first show this by taking any number below 1 out of the numbers array:

const positiveNumbers = numbers.filter(n => {
  return n > 0
})

// positiveNumbers = [5, 2, 3, 2, 4, 2]
// const numbers = [5, 2, -1, 3, 0, 2, 4, 2]

The 'n' in the numbers.filter() function just represents an individual value in the array as is is iterated over. So the function starts by passing in the first value (5) and returning true or false depending on whether 5 > 0. If true, 5 will be added to the new array. If false, it won't be included in the positiveNumbersArray. The function is non-descructive, so the numbers array remains the same.

Let's say we have a study group of all the people in the names array except for Matt. We can create a new array and filter him out.

const studyGroup = names.filter(name => {
  return name !== 'Matt'
})

// studyGroup = ['Zach', 'Laura', 'Jessica', 'Hannah']

Array.prototype.map()

The map function creates a new array using an existing array and operating over every value. For example:

const doubledNumbers = numbers.map(n => {
  return n * 2
})

// doubledNumbers = [10, 4, -2, 6, 0, 4, 8, 4]
// numbers = [5, 2, -1, 3, 0, 2, 4, 2]

In the above code, we define a new variable 'doubledNumbers'. The map function iterates over the numbers array, multiplying each value by two and adding them to a new array. The numbers array is left unchanged.

Let's say we want to take our array of names and create another array with welcome messages.

const welcomeMessages = names.map(name => {
  return `Welcome, ${name}!`
})

// welcomeMessages = ['Welcome, Zach!', 'Welcome, Laura!', 'Welcome, Matt!', 'Welcome, Jessica!', 'Welcome, Hannah!']

The names array is still unchanged, but now we have an array of all our welcome messages without having to hard-code a message for each name.

Array.prototype.reduce()

The reduce method is a bit more complex. The method is for tracking an array and reducing it to a single value. It also expects a function like filter and map, but can also take an initial value. For example:

// array.reduce(callbackFunction, initialValue)

const total = numbers.reduce((total, n) => {
  return total + n
}, 5)
// evaluates to 22

const total = numbers.reduce((total, n) => {
  return total - n
}, 0)
// evaluates to -17

const total = numbers.reduce((total, n) => {
  return total - n
})
// evaluates to -7

As seen in the last example, the reduce function doesn't require the initial value to be passed in. If no initial value is passed, it will start from the first value of the array. In the first example, 5 is passed in so the function's work as it iterates over the array looks like:

initialValue = 5
numbers = [5, 2, -1, 3, 0, 2, 4, 2]
5 + 5 = 10
10 + 2 = 12
12 + -1 = 11
11 + 3 = 14
14 + 0 = 14
14 + 2 = 16
16 + 4 = 20
20 + 2 = 22
return 22

The total starts at the initialValue passed in or the start of the array, then alters it as it iterates through the rest of the array, returning the final total when finished.

Array.prototype.sort()

The sort method is the one I had the hardest time understanding when I fist started learning how to code. I'll start by looking at the method without passing any arguments in.

const alphabetized = alpha.sort()

// alphabetized = ["a", "c", "d", "k", "r", "t", "v", "w", "y"]
// alpha = ["a", "c", "d", "k", "r", "t", "v", "w", "y"]

numbers.sort()

// numbers = [-1, 0, 2, 2, 2, 3, 4, 5]

Sort called without any arguments will sort from least to greatest ('a' < 'z' = true, 'Z' < 'a'). However, it will only compare the first character by default unless the first character is the same. Like 219 will be sorted before 3 since 2 < 3. 218 will be sorted before 22 since 2 = 2 so the second character will be evaluated. Sort basically sorts numbers alphabetically by default. The other important thing to note is that sort is destructive and changes the existing array rather than creating a new array.

However, the sort function does accept a function as an argument. Sort expects either a negative, 0, or a positive to be returned depending on how the two array values compare. Another way to write the default sort function is:

numbers.sort((a, b) => {
  if (a < b) {
    return -1
  } else if (a > b) {
    return 1
  } else {
    return 0
  }
})
// [-1, 0, 2, 2, 2, 3, 4, 5]

// To get reverse order, we switch the 1 and -1:

numbers.sort((a, b) => {
  if (a < b) {
    return 1
  } else if (a > b) {
    return -1
  } else {
    return 0
  }
})
// [5, 4, 3, 2, 2, 2, 0, -1]

However, since we're working with numbers, we don't need to manually return -1 or 1. Instead we can just write:

// from least to greatest
numbers.sort((a, b) => {
  return a - b
})

// from greatest to least
numbers.sort((a, b) => {
  return b - a
})

If a positive number is returned, the function will sort the next value before the previous value. If a negative number is returned, then the previous value will be sorted before the next. If a 0 is returned, there will be no change in order. I'll give another more example using an array of objects.

const family = [{
    role: 'mom',
    name: 'Ms. Smith',
    age: 45
  }, {
    role: 'dad',
    name: 'Mr. Smith',
    age: 45
  }, {
    role: 'sister',
    name: 'Hannah',
    age: 2
  }, {
    role: 'brother',
    name: 'Zach',
    age: 9
  }, {
    role: 'brother',
    name: 'Matt',
    age: 7
  }]

// we need to sort the family by ascending age
family.sort((a, b) => {
  return a.age - b.age
})

Now our family array is sorted by youngest to oldest.

Quick Note:

Feel free to drop a comment for any clarifications or corrections!

Top comments (1)

Collapse
 
anonymousm profile image
mludovici

maybe important to mention is that, map, reduce and filter do not modify the original object /array... but sort does