Return 使用 reduce 时未定义
Return undefined when using reduce
考虑以下数组:
const books = [
{
id: 1,
name: 'A song of ice and fire',
genre: 'Fantasy',
author: {
name: 'George R. R. Martin',
birthYear: 1948,
},
releaseYear: 1991,
},
{
id: 2,
name: 'The lord of the rings',
genre: 'Fantasy',
author: {
name: 'J. R. R. Tolkien',
birthYear: 1892,
},
releaseYear: 1954,
},
{
];
假设我想打印标题最长的书。以下作品:
const longestBook = () => {
const longestName = books.reduce((accumulator, book) => {
if (book.name.length > accumulator.name.length) {
return book;
}
return accumulator;
});
return longestName
}
console.log(longestBook().name);
我的问题是,为什么我不能直接return book.name / accumulator.name 而不是只在调用函数时使用.name?如果我尝试这样做,结果是不确定的。
const longestBook = () => {
const longestName = books.reduce((accumulator, book) => {
if (book.name.length > accumulator.name.length) {
return book.name;
}
return accumulator.name;
});
return longestName
}
console.log(longestBook());
如果累加器变为 .name
属性,它将是一个普通字符串,并且在下一次迭代中不再有 .name
属性 进行比较。
您需要通过提供初始值从一开始就与您的累加器类型保持一致。一个空字符串就足够了...
return books.reduce(
(acc, { name }) => name.length > acc ? name : acc,
"" // initial value
);
使用 reduce
,您将传递单个值 - 累加器 - 从上一次迭代到当前迭代。在 decently-structuredreduce 回调中,累加器通常应在整个循环中保持相同的形状,以便可以预测且一致地对其执行逻辑。
如果您尝试 return 仅 .name
,则会出现问题:
const longestName = books.reduce((accumulator, book) => {
if (book.name.length > accumulator.name.length) {
return book.name;
}
return accumulator.name;
});
因为
- 因为你没有提供初始值,第一次迭代的累加器将是第一本书object
- 在第一次迭代中,您 return 来自第一本书对象或第二本书对象的
.name
。名称是一个字符串,所以这导致累加器是第二次迭代的字符串
- 在第二次迭代中,累加器现在是一个字符串 - 而不是书籍对象 - 因此
return accumulator.name
不会 return 任何东西。
您将累积一个字符串而不是一个对象,因此您的整个 reduce()
方法都需要面向此。
这也意味着您需要为 reduce()
提供初始值。默认情况下,它采用数组的第一个值,这是一个对象,而不是字符串。
const books = [{
id: 1,
name: 'A song of ice and fire',
genre: 'Fantasy',
author: {
name: 'George R. R. Martin',
birthYear: 1948,
},
releaseYear: 1991,
}, {
id: 2,
name: 'The lord of the rings',
genre: 'Fantasy',
author: {
name: 'J. R. R. Tolkien',
birthYear: 1892,
},
releaseYear: 1954,
}];
const longestBook = () => {
const longestName = books.reduce((accumulator, { name }) => {
if (name.length > accumulator.length) {
return name;
}
return accumulator;
}, '');
return longestName;
}
console.log(longestBook());
考虑以下数组:
const books = [
{
id: 1,
name: 'A song of ice and fire',
genre: 'Fantasy',
author: {
name: 'George R. R. Martin',
birthYear: 1948,
},
releaseYear: 1991,
},
{
id: 2,
name: 'The lord of the rings',
genre: 'Fantasy',
author: {
name: 'J. R. R. Tolkien',
birthYear: 1892,
},
releaseYear: 1954,
},
{
];
假设我想打印标题最长的书。以下作品:
const longestBook = () => {
const longestName = books.reduce((accumulator, book) => {
if (book.name.length > accumulator.name.length) {
return book;
}
return accumulator;
});
return longestName
}
console.log(longestBook().name);
我的问题是,为什么我不能直接return book.name / accumulator.name 而不是只在调用函数时使用.name?如果我尝试这样做,结果是不确定的。
const longestBook = () => {
const longestName = books.reduce((accumulator, book) => {
if (book.name.length > accumulator.name.length) {
return book.name;
}
return accumulator.name;
});
return longestName
}
console.log(longestBook());
如果累加器变为 .name
属性,它将是一个普通字符串,并且在下一次迭代中不再有 .name
属性 进行比较。
您需要通过提供初始值从一开始就与您的累加器类型保持一致。一个空字符串就足够了...
return books.reduce(
(acc, { name }) => name.length > acc ? name : acc,
"" // initial value
);
使用 reduce
,您将传递单个值 - 累加器 - 从上一次迭代到当前迭代。在 decently-structuredreduce 回调中,累加器通常应在整个循环中保持相同的形状,以便可以预测且一致地对其执行逻辑。
如果您尝试 return 仅 .name
,则会出现问题:
const longestName = books.reduce((accumulator, book) => {
if (book.name.length > accumulator.name.length) {
return book.name;
}
return accumulator.name;
});
因为
- 因为你没有提供初始值,第一次迭代的累加器将是第一本书object
- 在第一次迭代中,您 return 来自第一本书对象或第二本书对象的
.name
。名称是一个字符串,所以这导致累加器是第二次迭代的字符串 - 在第二次迭代中,累加器现在是一个字符串 - 而不是书籍对象 - 因此
return accumulator.name
不会 return 任何东西。
您将累积一个字符串而不是一个对象,因此您的整个 reduce()
方法都需要面向此。
这也意味着您需要为 reduce()
提供初始值。默认情况下,它采用数组的第一个值,这是一个对象,而不是字符串。
const books = [{
id: 1,
name: 'A song of ice and fire',
genre: 'Fantasy',
author: {
name: 'George R. R. Martin',
birthYear: 1948,
},
releaseYear: 1991,
}, {
id: 2,
name: 'The lord of the rings',
genre: 'Fantasy',
author: {
name: 'J. R. R. Tolkien',
birthYear: 1892,
},
releaseYear: 1954,
}];
const longestBook = () => {
const longestName = books.reduce((accumulator, { name }) => {
if (name.length > accumulator.length) {
return name;
}
return accumulator;
}, '');
return longestName;
}
console.log(longestBook());