TypeScript和数组reduce函数

119

你知道 TypeScript 中的 reduce 数组方法是做什么用的吗?你能提供一个简单的使用示例吗?

我在谷歌上搜索和 TypeScript 语言规范中的文档,但是没有找到像样的解释和示例。

6个回答

168

除了其他回答之外,这里需要补充一点。

如果reduce提供了初始值,则有时必须指定其类型,即:

a.reduce(fn, [])

可能需要

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

8
被接受的答案没有解释累加器可以用任何对象初始化,因此也可以是不同类型的对象。 - Quentin 2
20
我认为语法现在已更改为a.reduce(fn, [] as string[]) - Cuga
以上代码是有效的,但如果我像[22,'foo'] as [number,string]这样定义一个更复杂的累加器时,就会出现“无法匹配任何重载”错误。我可以使用对象字面量({x:22,y:'foo'})来使它工作。有什么想法吗? - Sasgorilla
你必须在回调函数的第一个参数中定义相同的类型。 - Andres Felipe
除了输入初始值之外,您还可以输入回调函数的第一个参数:a.reduce((all: string[], v) => {...}, [])。我认为这是一种更清晰的解决方案,因为它仅定义了一个普通的参数类型,而不是类型转换。 - phil294

92

实际上,这是JavaScript数组的reduce函数,而不是TypeScript特有的。

根据文档所述:将一个函数应用于累加器和数组中每个值(从左到右),以将其减少为单个值。

下面是一个示例,它将数组中的值相加:

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

这段代码应该输出 6


4
这个说法正确吗?TypeScript文档和VS中的智能感知显示的是“previous element”而不是“accumulator”。 - Ewan
2
@Ewan 是的。如果你发现文档中将其称为“previous”而不是“accumulator”,那么它指的是从上一次调用 reducer 函数返回的累加器的值。 - JohnnyHK
1
永远不要忘记最后一个参数0,否则可能会引起棘手的错误。 - l-portet
1
永远不要忘记最后一个参数0,这可能会引发棘手的错误。 - l-portet

21

有了TypeScript的泛型,你可以做到这样。

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);

11

Reduce()是..

  • reduce()方法将数组缩减为单个值。
  • reduce()方法对数组的每个值(从左到右)执行一个提供的函数。
  • 函数的返回值存储在累加器(结果/总数)中。

它是..

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

更改至

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

此外,您可以在以下情况下使用:

  1. 查找最大值
    let array=[5,4,19,2,7];
    function findMax(acc,val)
    {
     if(val>acc){
       acc=val; 
     }
    }

    let biggest=arrays.reduce(findMax); // 19
  1. 找到一个不重复的元素
    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

6

+1给@JohnnyHK的回答,这是一个标准的JavaScript函数。

我来到这里是因为在输入这个函数时遇到了一些问题,所以我会在这里分享我的发现。如果你使用标准的IDE,如果你点击reduce函数,你将得到它的类型定义。

/**
 * 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;

第一个集合用于将数组 T 缩减为 T 值本身。

还有第二种用法,由 @Quentin 提到,就是你可能想将数组 T 缩减为其他类型。我经常看到它被用作:

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

0

一个简单的例子,计算数值数组的乘积。我经常忘记的是将参数作为初始累加器传递时使用变量类型语法。

const product = (nums: number[]): number => nums.reduce((acc: number, v: number): number => acc * v, 1 as number);
alert(product([1, 2, 3, 4]));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接