我如何使用 reduce() 来模仿 forEach() 的功能?

How do I use reduce() to mimic the capabilities of forEach()?

我正在尝试用 reduce() 完成我知道如何用 forEach() 完成的任务。不幸的是,我不确定如何构建语法,也找不到好的示例。

示例 1) 在这段代码中,我使用 forEach() 将单词 species 插入到每个数组的第一个索引中。

"use strict";

var creatureArray;

creatureArray = [
  ['zombie', 30, 1, 'bite', 0, 5],
  ['skeleton', 10, 2, 'sword', 1, 10],
  ['orc', 15, 4, 'club', 1, 7]
];

creatureArray.forEach(function(value, index, array) {
  array[index].unshift('species');
});

console.log(creatureArray);

示例 2) 在这段代码中,我尝试使用 .reduce() 完成类似的事情。但是我知道我缺少一段语法。我不知道如何将更新后的数组应用于累加器,然后将其作为对象返回。非常感谢您的帮助!

"use strict";

var creatureArray, creatureObject;

creatureArray = [
  ['zombie', 30, 1, 'bite', 0, 5],
  ['skeleton', 10, 2, 'sword', 1, 10],
  ['orc', 15, 4, 'club', 1, 7]
];

creatureObject = creatureArray.reduce(function(accumulator, currentValue, index, array) {
  array[index].unshift('species');
  //what goes here?
  return accumulator;
}, {});

console.log(creatureObject);

这里是你如何做到的。

"use strict";

var creatureArray, creatureObject;

creatureArray = [
  ['zombie', 30, 1, 'bite', 0, 5],
  ['skeleton', 10, 2, 'sword', 1, 10],
  ['orc', 15, 4, 'club', 1, 7]
];

creatureObject = creatureArray.reduce((accumulator, currentValue) => {
  return [...accumulator, ['species', ...currentValue]];
}, []);

console.log(creatureObject);

上面的 ... 语法称为 Spread Operator.

应用时,它会将数组的元素扩展到由封闭的 [] 创建的新数组中,将旧数组中的每个元素作为顶级元素放入新数组中.这导致平面数组而不是嵌套数组。例如 [[1, 2]] -> [[1, 2]],但 [...[1, 2]] -> [1, 2]。 这非常有用,因为它既可以实现简单的串联,也可以在扩展数组之前或之后插入顶级元素。

考虑:

"use strict";

const names = ['Linus', 'Jane', 'David'];

const withJakeAppended = [...names, 'Jake'];

const withJakePrepended = ['Jake', ...names];

[names, withJakeAppended, withJakePrepended].forEach(xs => console.log(xs));

如您所见,当我们展开一个数组时,它并没有被修改,因此令人愉快的语法还可以改进不可变的、面向价值的编程的人体工程学。

更好的是,... 也适用于 Sets 和 Maps。事实上,它适用于任何 Iterable 对象,包括我们可以自己创建的对象。

我可能会补充说,将第四个参数用于 Array.prototype.forEachArray.prototype.forEach 是一种应该避免的不良做法。

注意如果你需要在不支持ES2015的浏览器中这样做,你可以这样写

"use strict";

var creatureArray, creatureObject;

creatureArray = [
  ['zombie', 30, 1, 'bite', 0, 5],
  ['skeleton', 10, 2, 'sword', 1, 10],
  ['orc', 15, 4, 'club', 1, 7]
];

creatureObject = creatureArray.reduce(function (accumulator, currentValue) {

  return accumulator.concat([['species'].concat(currentValue)]);
}, []);

console.log(creatureObject);

map 在这种情况下更合适:

var creatureArray = [ ['zombie'  , 30, 1, 'bite' , 0,  5],
                      ['skeleton', 10, 2, 'sword', 1, 10],
                      ['orc'     , 15, 4, 'club' , 1,  7] ]

var creatureObject = creatureArray.map(currentValue => ['species', ...currentValue] )

console.log( JSON.stringify( creatureObject ).replace(/],/g, '],\n ') )