问题描述
盯着这个至少 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
值将是数组中的第一个子数组,所以 {{ 1}}。但是,当我尝试执行这样的步骤时,我的结果没有意义。我的思路是这样的:
['Title','Oliver Twist']
-
arr.reduce((a,v) => ((a[v[0]] = v[1]),{})
=a
和{}
=v
-
替换表达式中的 a 和 v,我们将:
arr.reduce((a,v) => (({}[['Title','Oliver Twist'][0]] = ['Title','Oliver Twist'][1]),{}),{})
-
['Title','Oliver Twist']
的{{1}}索引值为[0]
,v
的{{1}}索引值为'Title'
,所以我们可以将表达式缩短为:arr.reduce((a,v) => (({}Title = Oliver Twist)、{})、{})
-
这里是我开始感到困惑的地方,因为在第一次运行
[1]
函数之后,我的新累加器或v
值似乎是'Oliver Twist'
,当我第二次尝试将其替换为reduce
时,这没有任何意义。
我错过了什么? a
不是初始化程序吗? ({}Title = Oliver Twist),{})
是否只是告诉它将结果答案括在 a
中?无法很好地理解如何使用 {}
对将其格式化为对象!
解决方法
那里的 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
});
};
空对象是累加器的初始值,它在每次迭代时获得一个分配给它的属性。对象不会保持为空。
看来我的新累加器或值是 ({}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
部分实际上是 return a
的简写。我一直试图再次将 a
的值插入那个位置,这就是为什么我的结果总是返回一些奇怪的无效语法。
我原来的代码行,
const object_From_Pairs = arr => arr.reduce((a,{});
可以这样改写:
const object_From_Pairs = arr => arr.reduce((a,{});
另外,澄清 {}
是我们传递给 a
的初始值。
非常感谢@Certain Performance 的详尽解答!