我有兴趣了解该算法内部发生的情况。让我们考虑以下数据集:
const data = [
{
emp_code: "a001",
company_code: "company_a",
name: "abx",
details: [],
details_dtypes: []
},
{
emp_code: "b002",
company_code: "company_b",
name: "xbz ",
details: [],
details_dtypes: []
},
{
emp_code: "a002",
company_code: "company_a",
name: "xbz ",
details: [],
details_dtypes: []
},
{
emp_code: "b003",
company_code: "company_b",
name: "xbz ",
details: [],
details_dtypes: []
}
];
现在,如果我想将这些数据压缩为一个 object {}
,其中每个键都是唯一的 company_code
,其对应的值是一个 array [ ]
的 emp_codes
对于该公司,我可以做类似的事情:
let result = data.reduce((r, c) => {
r[c.company_code] = [...(r[c.company_code] || []), c.emp_code];
return r;
}, {});
在上面,我们显式返回了最终的对象,这看起来很清楚。
现在,我最近发现您可以使用一些语法糖来缩短它,如下所示:
let result = data.reduce(
(r, c) =>
(r[c.company_code] = [...(r[c.company_code] || []), c.emp_code]) && r,
{}
);
结果是相同的,但我不确定这怎么可能。我对reduce()的理解是,有一个内循环迭代每个项目,并允许您应用某些逻辑来制定最终结果。
我发现他们正在使用 &&
运算符。我的假设是括号 ()
之间的逻辑像传统的 reduce()
方法一样执行,完成后,我们只需返回结果,因此 && r
.
但这似乎有些不对劲。内循环还在发生吗?如果是的话,他们如何能够像这样隔离它,而无需在第一次迭代后简单地执行条件,从而返回r
。他们是否为循环的每次迭代返回r
?
这是一个沙箱,显示两种算法的工作情况:https://codesandbox.io/s/hooks-with-reduce-nested-data-goee1 。非常感谢您的贡献:)
最佳答案
使用 &&
时,如果涉及的所有表达式均为真,则其计算结果为最终表达式的值 - 即 &&
之后的表达式。因此,如果您有如下代码:
function foo() {
<some expression>;
return bar;
}
你也可以这样写
function foo() {
return <some expression> && bar;
}
或者,使用箭头函数的隐式返回:
const foo = () => <some expression> && bar;
这相当于
const foo = () => {
<some expression>;
return bar;
};
所以,是的,对于您的代码,在箭头函数末尾使用 && r
,这意味着 r
在每次迭代时都会隐式返回。
尽管如此,这几乎与语法糖的相反。如果您通过压缩器运行代码,您会经常看到这种情况,压缩器的目标是尽可能减少 Javascript 中的文本量。但缩小的代码通常很难阅读,这也不异常(exception),正如您的问题所示。如果使用隐式 return
需要逗号运算符或利用 &&
作为 bool 值以外的其他计算,则代码可能太困惑而难以阅读,而显式的return
可能是更好的选择。
您还可以考虑推送到累加器对象中的现有数组,从而避免创建许多不必要的中间数组,这些数组只会在以后传播:
let result = data.reduce((r, c) => {
if (!r[c.company_code]) {
r[c.company_code] = [];
}
r[c.company_code].push(c.emp_code);
return r;
}, {});
这是我更喜欢的代码。它有点长,但是当每个语句/逻辑分支都在自己的行上时,它更容易阅读很多。
关于javascript - ES6 中的 Array.reduce(),隐式返回和语法糖。到底发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56731075/