Javascript:无法理解 Reduce 函数中的空初始值设定项

Javascript: Having Trouble Understanding Empty Initializer in Reduce Function

看了这个至少 4 个小时,才最终决定联系各位专家。

JS 新手。本练习的目标是从一些给定的键值对创建一个对象。我以一种有效的方式做到了,但是,我很难理解提供的这个示例解决方案:

const object_From_Pairs = arr => arr.reduce((a, v) => 
  ((a[v[0]] = v[1]), a), {});
console.log(object_From_Pairs([['Title', 'Oliver Twist'], ['Author', 'Charles Dickens']]));
// Output: {Title: "Oliver Twist", Author: "Charles Dickens"}

我了解如何使用 reduce 函数,但我对传递空初始化值(如 {}[] 时发生的情况感到困惑。

根据 MDN web docs on the reduce function,第一次执行循环时,累加器将是您可以选择提供的初始值(逗号后),您的值将是您要经过的数组中的第一项。

如果这种思路是正确的,我的初始 a 值似乎是 {},而我的 v 值将是数组中的第一个子数组,所以['Title', 'Oliver Twist']。但是,当我尝试执行这些步骤时,我的结果没有任何意义。我的思路是这样的:

arr.reduce((a, v) => ((a[v[0]] = v[1]), a), {})
  1. a = {}v = ['Title', 'Oliver Twist']

  2. 替换表达式中的 a 和 v,我们将有:

    arr.reduce((a, v) => (({}[['Title', 'Oliver Twist'][0]] = ['Title', 'Oliver Twist'][1]), {}), {})

  3. v[0]索引值为'Title'v[1]索引值为'Oliver Twist',所以我们可以将表达式缩短为:

    arr.reduce((a, v) => (({}Title = Oliver Twist), {}), {})

  4. 这是我开始感到困惑的地方,因为在 运行 第一次通过 reduce 函数之后,似乎我的新累加器或 a值将是 ({}Title = Oliver Twist), {}),当我第二次尝试将其替换为 a 时,这没有意义。

我错过了什么? {} 不是初始值设定项吗? {} 是否只是告诉它在 {} 中包围结果答案?无法很好地理解如何将 key: value 对格式化为对象!

那里的 reduce 做的事情稍微复杂一些。它不仅分配给累加器 a 的 属性,它还 返回 累加器。此代码:

const object_From_Pairs = arr => arr.reduce((a, v) => 
  ((a[v[0]] = v[1]), a), {});

相当于:

const object_From_Pairs = arr => arr.reduce((a, v) => {
  a[v[0]] = v[1];
  return a;
}, {});

相当于

const object_From_Pairs = arr => {
  const a = {};
  arr.forEach((v) => {
    a[v[0]] = v[1];
    // there's no need to do anything with a here
    // since the a you want to refer to is already in the outer scope
  });
};

空对象是累加器的初始值,每次迭代都会为它分配一个 属性。该对象不会保持为空。

it seems my new accumulator or a value would be ({}Title = Oliver Twist), {})

这不是有效的语法。在第二次迭代中,a 的值为

{ Title: 'Oliver Twist' }

所以运行的回调:

((a[v[0]] = v[1]), a)

就像

let a = { Title: 'Oliver Twist' };
return ((a[v[0]] = v[1]), a)

或者,没有令人困惑的逗号运算符:

let a = { Title: 'Oliver Twist' };
a[v[0]] = v[1];
return a;

更好的是,我强烈建议在这种情况下避免使用 .reduce - IMO 每次累加器的值都相同时,它只是 not all that appropriate。请改用普通循环。 arr.forEachfor (const subarr of arr).

对于这种特殊情况,有一个更好的选择,允许将键值子数组的数组转换为单个对象:

const object_From_Pairs = Object.fromEntries;
console.log(object_From_Pairs([['Title', 'Oliver Twist'], ['Author', 'Charles Dickens']]));
// Output: {Title: "Oliver Twist", Author: "Charles Dickens"}

完成:)

已回答!我的主要困惑是没有意识到表达式的 ,a 部分实际上是 shorthand for return a。我一直试图再次将 a 的值插入到那个位置,这就是为什么我的结果不断返回一些奇怪的无效语法。

我原来的代码行,

const object_From_Pairs = arr => arr.reduce((a, v) => 
  ((a[v[0]] = v[1]), a), {});

可以改写成这样:

const object_From_Pairs = arr => arr.reduce((a, v) => {
  a[v[0]] = v[1];
  return a;
}, {});

此外,澄清了 {} 是我们传递给 a 的初始值。

非常感谢@Certain Performance的详尽回答!