【问题标题】:How to define a function in javascript reduce function?如何在javascript reduce函数中定义一个函数?
【发布时间】:2021-12-14 00:45:39
【问题描述】:

我有一个对象 student,它有属性 id、name、groupName。 allStudents 是学生对象的数组,我想把它变成一个id to student map,但是对于每个学生,我想生成一个新的属性“label”,如果学生有groupName,label值是“name + groupName” ,否则为名称。所以我写了下面的代码,它可以工作:

const idsToStudents = allStudents.reduce((tempMap, student) => {
    const getStudentLabel = (student) => {
        if (student.groupName) {
            return [student.name, `(${student.groupName})`].join(' ');
        }
        return student.name;
    };
    const studentLabel = getStudentLabel(student);
    return {
        ...tempMap,
        [student.id]: { ...student, label: studentLabel}
    };
}, {});

我在 reducer 函数中定义了 getStudentLabel 函数,有没有更好的方法来代替在 reducer 函数中一次又一次地声明 getStudentLabel 函数?你可以忽略 getStudentLabel 到底做了什么,只是认为它将每个人作为参数并根据人返回一些东西,有没有办法只定义一次函数,但我仍然可以为减速器中的每个人调用它?

谢谢!

【问题讨论】:

  • 为什么不把getStudentLabel移出reducer呢?我不明白为什么它在里面你不希望它在里面。那么..它存在的确切原因是什么?

标签: javascript arrays function object reducers


【解决方案1】:

Object.fromEntries 可以代替reduce 工作。

const getStudentLabel = ({name, groupName}) => groupName
  ? name + ` (${groupName})`
  : name;

const idsToStudents = Object.fromEntries(
  allStudents.map(student => [student.id, { ...student, label: getStudentLabel(student) }])
);

【讨论】:

    【解决方案2】:

    我不会担心在闭包中重新定义函数。任何合理的 javascript 实现都会对其进行优化,以便使用最少的额外内存。我不会说你不止一次地“定义”函数是准确的——你只在代码中定义了一次。该函数每次都被实例化,但该实例化将利用函数静态部分的缓存。所以你这样做的方式非常好。正如 Ori Drori 所提到的,您不必必须在内部函数中包含 student 变量,但无论如何这可能是个好主意,这样您就可以非常明确地了解函数的依赖关系。

    【讨论】:

      【解决方案3】:

      您将student 作为参数传递给函数,因此您无需在reduce 中声明它。这也可以:

      const getStudentLabel = (student) => {
        if (student.groupName) {
          return [student.name, `(${student.groupName})`].join(' ');
        }
        
        return student.name;
      };
      
      const idsToStudents = allStudents.reduce((tempMap, student) => {
        const studentLabel = getStudentLabel(student);
        return {
            ...tempMap,
            [student.id]: { ...student, label: studentLabel}
        };
      }, {});
      

      你还可以稍微缩短代码:

      const getStudentLabel = ({ name, groupName }) => groupName
        ? `${name} (${groupName})`
        : name;
      
      const idsToStudents = allStudents.reduce((tempMap, student) => ({
        ...tempMap,
        [student.id]: { ...student, label: getStudentLabel(student) }
      }), {});
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多