如何在javascriptreduce函数中定义一个函数?
How to define a function in javascript reduce function?
我有一个学生对象,它有 属性 id、name、groupName。
allStudents 是学生对象的数组,我想把它变成一个 id 到 student 映射,但是对于每个学生,我想生成一个新的 属性 “label”,如果学生有 groupName,label 值为“ name + groupName”,否则就是name。所以我写了下面的代码,它有效:
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 到底做了什么,只是认为它把每个人作为参数和 return 一些基于人的东西,有没有办法只定义一次函数,但我仍然可以为 reducer 中的每个人调用它?
谢谢!
您将 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) }
}), {});
我不担心在闭包内重新定义函数。任何合理的 javascript 实现都会对其进行优化,以便使用最少的额外内存。我不会说您不止一次“定义”该函数是准确的-您只在代码中定义了一次。函数每次都被实例化,但是这个实例化将利用函数静态部分的缓存。所以你这样做的方式非常好。正如 Ori Drori 提到的那样,您不必 必须 在内部函数中使用 student 变量,但无论如何这样做可能是个好主意,这样您就可以非常明确地了解函数的依赖项。
Object.fromEntries
可以替代 reduce
.
const getStudentLabel = ({name, groupName}) => groupName
? name + ` (${groupName})`
: name;
const idsToStudents = Object.fromEntries(
allStudents.map(student => [student.id, { ...student, label: getStudentLabel(student) }])
);
我有一个学生对象,它有 属性 id、name、groupName。 allStudents 是学生对象的数组,我想把它变成一个 id 到 student 映射,但是对于每个学生,我想生成一个新的 属性 “label”,如果学生有 groupName,label 值为“ name + groupName”,否则就是name。所以我写了下面的代码,它有效:
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 到底做了什么,只是认为它把每个人作为参数和 return 一些基于人的东西,有没有办法只定义一次函数,但我仍然可以为 reducer 中的每个人调用它?
谢谢!
您将 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) }
}), {});
我不担心在闭包内重新定义函数。任何合理的 javascript 实现都会对其进行优化,以便使用最少的额外内存。我不会说您不止一次“定义”该函数是准确的-您只在代码中定义了一次。函数每次都被实例化,但是这个实例化将利用函数静态部分的缓存。所以你这样做的方式非常好。正如 Ori Drori 提到的那样,您不必 必须 在内部函数中使用 student 变量,但无论如何这样做可能是个好主意,这样您就可以非常明确地了解函数的依赖项。
Object.fromEntries
可以替代 reduce
.
const getStudentLabel = ({name, groupName}) => groupName
? name + ` (${groupName})`
: name;
const idsToStudents = Object.fromEntries(
allStudents.map(student => [student.id, { ...student, label: getStudentLabel(student) }])
);