TypeScript and array reduce function

215,064

Solution 1

It's actually the JavaScript array reduce function rather than being something specific to TypeScript.

As described in the docs: Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value.

Here's an example which sums up the values of an array:

let total = [0, 1, 2, 3].reduce((accumulator, currentValue) => accumulator + currentValue);
console.log(total);

The snippet should produce 6.

Solution 2

Just a note in addition to the other answers.

If an initial value is supplied to reduce then sometimes its type must be specified, viz:-

a.reduce(fn, [])

may have to be

a.reduce<string[]>(fn, [])

or

a.reduce(fn, <string[]>[])

Solution 3

With TypeScript generics you can do something like this.

class Person {
    constructor (public Name : string, public Age: number) {}
}

var list = new Array<Person>();
list.push(new Person("Baby", 1));
list.push(new Person("Toddler", 2));
list.push(new Person("Teen", 14));
list.push(new Person("Adult", 25));

var oldest_person = list.reduce( (a, b) => a.Age > b.Age ? a : b );
alert(oldest_person.Name);

Solution 4

Reduce() is..

  • The reduce() method reduces the array to a single value.
  • The reduce() method executes a provided function for each value of the array (from left-to-right).
  • The return value of the function is stored in an accumulator (result/total).

It was ..

let array=[1,2,3];
function sum(acc,val){ return acc+val;} // => can change to (acc,val)=>acc+val
let answer= array.reduce(sum); // answer is 6

Change to

let array=[1,2,3];
let answer=arrays.reduce((acc,val)=>acc+val);

Also you can use in

  1. find max
    let array=[5,4,19,2,7];
    function findMax(acc,val)
    {
     if(val>acc){
       acc=val; 
     }
    }

    let biggest=arrays.reduce(findMax); // 19
  1. find an element that not repeated.
    arr = [1, 2, 5, 4, 6, 8, 9, 2, 1, 4, 5, 8, 9]
    v = 0
    for i in range(len(arr)):
    v = v ^ arr[i]
    print(value)  //6

Solution 5

+1 for @JohnnyHK answer that it's a standard Javascript function.

I landed here because I got some issues with typing this function, so I'll leave my findings here. If you have a standard IDE if you click on reduce function you will get the type definitions for it.

/**
 * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
 * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
 * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
 */
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T): T;
reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue: T): T;


/**
 * Calls the specified callback function for all the elements in an array. The return value of the callback function is the accumulated result, and is provided as an argument in the next call to the callback function.
 * @param callbackfn A function that accepts up to four arguments. The reduce method calls the callbackfn function one time for each element in the array.
 * @param initialValue If initialValue is specified, it is used as the initial value to start the accumulation. The first call to the callbackfn function provides this value as an argument instead of an array value.
 */
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;

First set is for reducing array of T to the T value itself.

There is also 2nd usage, mentioned by @Quentin, which is that you might want to reduce array of T to some other type. Most often I saw it being used as:

const keyToValMap = [{key: 'k1', val: 1}].reduce<Record<string, number>>((map, el) => {
  map[el.key] = el.val;
  return map
}, {})
Share:
215,064

Related videos on Youtube

Tom
Author by

Tom

Architect and enthusiast programmer. Personal website GitHub

Updated on March 04, 2022

Comments

  • Tom
    Tom over 2 years

    Do you know what the reduce array method does in TypeScript? Can you provide a simple example of usage?

    I searched on Google and the TypeScript language specification but could not find any decent explanation and examples.

  • Quentin 2
    Quentin 2 over 6 years
    The accepted answer omits to explain that the accumulator can be initialised with any object and so can be of a different type too.
  • Cuga
    Cuga over 5 years
    I think the syntax has now changed to a.reduce(fn, [] as string[])
  • Ewan
    Ewan about 4 years
    is this correct? the typescript documentation and intellisense in VS say its previous element rather than accumulator.
  • JohnnyHK
    JohnnyHK about 4 years
    @Ewan Yes. If you find docs calling it previous rather than accumulator, it's referring to the value of the accumulator as returned from the previous call to the reducer function.
  • Sasgorilla
    Sasgorilla almost 3 years
    This works as written above, but I can't define a more complicated accumulator like [22, 'foo'] as [number, string] -- I get a No overload matches this call error. I can make it work with an object literal ({x: 22, y: 'foo'}). Any idea why?
  • Andres Felipe
    Andres Felipe over 2 years
    You got to define the same types on the 1st param of the callback function.
  • phil294
    phil294 about 2 years
    Alternatively to typing the initial value, you can also type the first argument of the callback: a.reduce((all: string[], v) => {...}, []). I think this is a cleaner solution as it merely defines a normal parameter type instead of a type cast