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), {})
a
= {}
和 v
= ['Title', 'Oliver Twist']
替换表达式中的 a 和 v,我们将有:
arr.reduce((a, v) =>
(({}[['Title', 'Oliver Twist'][0]] = ['Title', 'Oliver Twist'][1]), {}), {})
v
的[0]
索引值为'Title'
,v
的[1]
索引值为'Oliver Twist'
,所以我们可以将表达式缩短为:
arr.reduce((a, v) =>
(({}Title = Oliver Twist), {}), {})
这是我开始感到困惑的地方,因为在 运行 第一次通过 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.forEach
或 for (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的详尽回答!
看了这个至少 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), {})
a
={}
和v
=['Title', 'Oliver Twist']
替换表达式中的 a 和 v,我们将有:
arr.reduce((a, v) => (({}[['Title', 'Oliver Twist'][0]] = ['Title', 'Oliver Twist'][1]), {}), {})
v
的[0]
索引值为'Title'
,v
的[1]
索引值为'Oliver Twist'
,所以我们可以将表达式缩短为:arr.reduce((a, v) => (({}Title = Oliver Twist), {}), {})
这是我开始感到困惑的地方,因为在 运行 第一次通过
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.forEach
或 for (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的详尽回答!