javascript - ES6 中的 Array.reduce(),隐式返回和语法糖。到底发生了什么?

标签 javascript arrays ecmascript-6

我有兴趣了解该算法内部发生的情况。让我们考虑以下数据集:

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/

相关文章:

c - 打印数组元素给出错误的输出

python - 在 PyTorch 中将张量向量化分配给切片

javascript - JS indexOf 对象数组和 splice() 没有删除正确的对象

javascript - 类型错误 : Error resolving module specifier

javascript - Vue.js 无法使用 querySelector 找到元素

java - 如何从 Java 6 中的字节数组中获取 MIME 类型?

javascript - 对 JavaScript 文件的动态引用

css - 如何使用 React 改变鼠标移到按钮上时的颜色?

javascript - Vagrant VM 中 Ubuntu 上的 nginx 中途随机停止发送 JS 文件

Javascript 应用无法正常工作