使用reduce汇总数据

与数组有关的另一个常见事情是从它们中计算单个值。 我们的递归示例,汇总了一系列数字,就是这样一个例子。 另一个例子是找到字符最多的脚本。

表示这种模式的高阶操作称为归约(reduce)(有时也称为折叠(fold))。 它通过反复从数组中获取单个元素,并将其与当前值合并来构建一个值。 在对数字进行求和时,首先从数字零开始,对于每个元素,将其与总和相加。

reduce函数包含三个参数:数组、执行合并操作的函数和初始值。该函数没有filtermap那样直观,所以仔细看看:

  1. function reduce(array, combine, start) {
  2. let current = start;
  3. for (let element of array) {
  4. current = combine(current, element);
  5. }
  6. return current;
  7. }
  8. console.log(reduce([1, 2, 3, 4], (a, b) => a + b, 0));
  9. // → 10

数组中有一个标准的reduce方法,当然和我们上面看到的那个函数一致,可以简化合并操作。如果你的数组中包含多个元素,在调用reduce方法的时候忽略了start参数,那么该方法将会使用数组中的第一个元素作为初始值,并从第二个元素开始执行合并操作。

  1. console.log([1, 2, 3, 4].reduce((a, b) => a + b));
  2. // → 10

为了使用reduce(两次)来查找字符最多的脚本,我们可以这样写:

  1. function characterCount(script) {
  2. return script.ranges.reduce((count, [from, to]) => {
  3. return count + (to - from);
  4. }, 0);
  5. }
  6. console.log(SCRIPTS.reduce((a, b) => {
  7. return characterCount(a) < characterCount(b) ? b : a;
  8. }));
  9. // → {name: "Han", …}

characterCount函数通过累加范围的大小,来减少分配给脚本的范围。 请注意归约器函数的参数列表中使用的解构。 `reduce’的第二次调用通过重复比较两个脚本并返回更大的脚本,使用它来查找最大的脚本。

Unicode 标准分配了超过 89,000 个字符给汉字脚本,它成为数据集中迄今为止最大的书写系统。 汉字是一种(有时)用于中文,日文和韩文的文字。 这些语言共享很多字符,尽管他们倾向于以不同的方式写它们。 (基于美国的)Unicode 联盟决定将它们看做一个单独的书写系统来保存字符码。 这被称为中日韩越统一表意文字(Han unification),并且仍然使一些人非常生气。