skip to Main Content

I was trying to find a solution to find out the number of occurrences of a number in an array and came across the below solution:

const occurrences = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
  return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});

console.log(occurrences)

The code above works as expected. But I am not able to understand properly how it works. Can someone please simplify and explain the reduce method above? Thanks in advance.

2

Answers


  1. I assume the tricky part is just:

    return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
    

    Note that this is just:

    return (some_expression_with_side_effects), acc
    

    …which returns acc. Take a look at the comma operator in JavaScript for details. In short, the expression a, b equals b. Using this as a return value for reduce just ensures that the the accumulator is always the same object acc. But we add properties to that object as we reduce.

    As we reduce items in the array, the side-effect expression does the following:

    • if there is a count for the current item, then increment it
    • if there is not a count yet, then add it and initialize it to 1.

    Note that we don’t actually use the return value of ++acc[curr], we just rely on the side-effect that it actually increments the values stored at acc[curr]. And similarly, we don’t return the value of the expression acc[curr] = 1, but rather, we rely on the side-effect that it actually sets acc[curr] to an initial value of 1.

    Login or Signup to reply.
  2. The reduce() method in JavaScript is used to iterate over an array and based on some logic accumulate a single value from it.

    Let’s break down the code:

    const occurrences = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
        return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
    }, {});
    

    The reduce() method takes two arguments:

    A function that is executed on each element of the array. This function takes two parameters: the accumulator (acc) and the current value being processed (curr). The accumulator is the value that is returned and accumulated on each iteration of the function.

    An optional initial value for the accumulator. In this case, the initial value is an empty object {}.

    let’s find out the function being passed as the first argument to reduce():

    function (acc, curr) {
      return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
    }
    

    On each iteration, this function checks if the current value (curr) already exists as a key in the accumulator (acc). If it does, it increments the value of that key. If not, it adds the key to the accumulator with a value of 1.

    Breaking down the logic:

    return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
    
    • acc[curr] ?:This checks if the current value (curr) exists as a key in the accumulator (acc).

    • ++acc[curr]: If the key exists, it increments the value associated with that key.

    • : acc[curr] = 1: If the key does not exist, it adds the key to the accumulator with a value of 1.

    • , acc: Finally, the updated accumulator is returned.

    In each iteration, the reduce() method is either incrementing the count for an existing number or initializing a count of 1 for a new number in the acc object.

    After all the iterations are complete, the final value of the accumulator object is assigned to the occurrences variable and printed to the console:

    console.log(occurrences) // {2: 5, 4: 1, 5: 3, 9: 1}
    

    This shows that there are 5 occurrences of the number 2, 3 occurrences of the number 5, 1 occurrence of the number 4, and 1 occurrence of the number 9 in the original array.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search