JS.Help

JS.Help

    Array.prototype.reduce()

    The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in a single output value.

    Syntax

    array.reduce( (accumulator, currentValue, currentIndex, sourceArray) => {}, initialValue )
    
    • accumulator - accumulates the callback's return value. It is the accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied.
    • currentValue - the current element being processed in the array.
    • index - the index of the current element being proccessed in the array. Starts from index 0 if an initialValue is provided. Otherwise, starts from index 1.
    • array - the array reduce() was called upon.
    • initialValue - a value to use as the first argument to the first call of the callback. If no initialValue is supplied, the first element in the array will be used and skipped.

    index, array and initialValue - are optional.

    Basic Examples

    const sum = [4, 5, 32, 24, 8].reduce((acc, curNum)=>acc+curNum);
    // 4 + 5 + 32 + 24 + 8 
    console.log(sum);  // expected output: 73
    

    Common uses of reduce method

    Changing the data structure:

    const subjects = [
        { id: 1, name: 'Math', content: 'All about numbers and calculations' },
        { id: 2, name: 'Chemistry', content: 'All about matter, its properties and substances' },
        { id: 3, name: 'Physical training', content: 'All about fitness exersises' }
    ]
    
    const subjectsObj = subjects.reduce((acc, sub)=>{
        const { id, ...rest } = sub;
        return { ...acc, [id]: rest }
    }, {});
    
    console.log(subjectsObj);  
    
    /* expected output: 
        1: { name: "Math", content: "All about numbers and calculations" }
        2: { name: "Chemistry", content: "All about matter, its properties and substances" }
        3: { name: "Physical training", content: "All about fitness exersises" }
    */
    

    A vanilla JS equivalent of lodash's groupBy() method

    const colorGroups = [
      { color: "Orchid ", group: "Purple" },
      { color: "Teal", group: "Green" },
      { color: "Salmon", group: "Red" },
      { color: "Fuchsia", group: "Purple" },
      { color: "Indigo", group: "Purple" },
      { color: "Crimson ", group: "Red" },
      { color: "Lime", group: "Green" },
      { color: 'OliveDrab', group: 'Green' }
    ];
    
    function groupBy(arr, property) {
      return arr.reduce( (groupObj, colorObj) => {
        let key = colorObj[property];
        if(!(key in groupObj)) groupObj[key] = [];
        groupObj[key].push(colorObj);
        return groupObj;
      }, {});
    }
    
    console.log(groupBy(colorGroups, 'group'));  
    /*
      expected output: 
        {
            Purple: [ {color: "Teal", group: "Green"}, {color: "Lime", group: "Green"}, {color: "OliveDrab", group: "Green"} ],
            Green: [ {color: "Orchid ", group: "Purple"}, {color: "Fuchsia", group: "Purple"}, {color: "Indigo", group: "Purple"} ],
            Red: [ {color: "Salmon", group: "Red"}, {color: "Crimson ", group: "Red"} ]
        }
    */ 
    

    Counting of values

    const cars = ['Nissan', 'Renault', 'Ford', 'Honda', 'Ford', 'Toyota', 'Nissan', 'Ford'];
    
    let carsAmount = cars.reduce((carsObj, car) => {
      if (car in carsObj) {
        carsObj[car]++;
      } else {
        carsObj[car] = 1;
      }
      return carsObj;
    }, {});
    
    console.log('carsAmount', carsAmount);  // expected output: { Nissan: 2, Renault: 1, Ford: 3, Honda: 1, Toyota: 1 }
    

    Collect input values from a form:

    <form>
        <input type="text" name="firstname" placeholder="Enter first name" value="JS"/><br/>
        <input type="text" name="lastname" placeholder="Enter last name" value="help"><br/>
        <input type="email" name="email" placeholder="Enter e-mail" value="help@js.help"/><br/>
        <button type="submit">Submit</button>
    </form>
    
    let formEl = document.querySelector('form');
    formEl.addEventListener('submit', e => {
      const inputElsArr = [...e.currentTarget.querySelectorAll('input')];
      const formData = inputElsArr.reduce((data, inputEl)=>{
        const inputName = inputEl.getAttribute('name');
        const inputVal = inputEl.value;
        data[inputName] = inputVal
        return data;
      }, {})
      console.log('formData', formData);  // expected output: {firstname: 'JS', lastname: 'help', email: 'help@js.help'}
    });
    

    Promise chains

    When the order in which the promises should resolve is important

    const promiseQueue = (promiseFn, list) =>
      list.reduce(
        (queue, item) => queue.then(async result => {
          const itemResult = await promiseFn(item);
          return result.push(itemResult);
        }),
        Promise.resolve([])
      );
    

    List of methods and techniques which were used in the examples above and you may be curious to learn more about them:

    • addEventListener - adds a listener to the list of callbacks called when the specified event is fired.
    • querySelector - returns the first element that matches the specified selector.
    • querySelectorAll - returns a static NodeList repesending a list of elements that match the specified group of selectors.
    • getAttribute - returns the value of a specified attribute on the element.
    • in - returns true if the specifed property is in the speicified object.
    • async - an async function always returns a Promise.
    • destructuring

    List of Resources

    MDN: Array.prototype.reduce
    Medium: Explanation of javascript’s reduce() with a real world use case
    ITNEXT: Useful “reduce” use cases

    • Syntax
    • Basic Examples
    • Common uses of reduce method
      • Changing the data structure:
      • A vanilla JS equivalent of lodash's groupBy() method
      • Counting of values
      • Collect input values from a form:
      • Promise chains
      • List of methods and techniques which were used in the examples above and you may be curious to learn more about them:
    • List of Resources