[英]Why does Javascript .map() return and extra “undefined” for an object of strings?
映射字符串对象时,任何人都可以提供有关未定义项来自何处的帮助。 这是我的对象,后面是映射:
function giveAdminTasks(){
var item;
var arr = [{adminTask: "Print Certificate",lessonNo: 0},
{adminTask: "Study",lessonNo: 27},
{adminTask: "Print Certificate",lessonNo: 3},
{adminTask: "Calling Record",lessonNo: 3},
{adminTask:"Calling Record",lessonNo: 3}];
arr.map(function(elem){
if(elem.lessonNo === 3){
item += " + " + elem.adminTask;
}
})
console.log(item);
}
但是,这将返回如下所示的变量:
“未定义+打印证书+通话记录+通话记录”
我不知道“未定义”项目的来源。 如果我仅在没有“ if”语句的情况下映射对象,则不会发生这种情况。 有人可以帮忙吗?
这个问题是关于map仅在字符串上起作用的,但是我的对象是所有字符串。
您没有初始化item
变量,因此它的初始值为undefined
。
更改此:
var item;
对此:
var item = "";
您还必须处理以下事实: item
最初是空的,并且不想在空的情况下添加前导+
符号。
仅供参考,这实际上是对.map()
的滥用。 您应该使用.forEach()
或其他迭代器之一,因为您对返回的数组不感兴趣。
function giveAdminTasks() {
var item = "";
var arr = [
{adminTask: "Print Certificate", lessonNo: 0},
{adminTask: "Study", lessonNo: 27},
{adminTask: "Print Certificate", lessonNo: 3},
{adminTask: "Calling Record", lessonNo: 3},
{adminTask: "Calling Record",lessonNo: 3
}];
arr.forEach(function(elem) {
if (elem.lessonNo === 3) {
if (item) item += " + ";
item += elem.adminTask;
}
});
console.log(item);
}
您也可以像下面这样使用.reduce()
:
var item = arr.reduce(function(str, item) {
if (item.lessonNo === 3) {
if (str) str += " + ";
str += elem.adminTask;
}
return str;
}, "");
console.log(item);
这是使用ES6的更具声明性的解决方案。 它与Oriol的解决方案最相似,但不会多次遍历数据。
const giveAdminTasks = (data, n) => data.reduce((acc, {adminTask, lessonNo}) => lessonNo === n ? [...acc, adminTask] : acc, []).join(' + ') let arr = [ {adminTask: "Print Certificate",lessonNo: 0}, {adminTask: "Study",lessonNo: 27}, {adminTask: "Print Certificate",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3} ] console.log(giveAdminTasks(arr, 3)) // Print Certificate + Calling Record + Calling Record console.log(giveAdminTasks(arr, 0)) // Print Certificate console.log(giveAdminTasks(arr, 27)) // Study
和ES5相当
function giveAdminTasks (data, n) { return data.reduce(function (acc, x) { return x.lessonNo === n ? acc.concat([x.adminTask]) : acc }, []).join(' + ') } var arr = [ {adminTask: "Print Certificate",lessonNo: 0}, {adminTask: "Study",lessonNo: 27}, {adminTask: "Print Certificate",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3} ] console.log(giveAdminTasks(arr, 3)) // Print Certificate + Calling Record + Calling Record console.log(giveAdminTasks(arr, 0)) // Print Certificate console.log(giveAdminTasks(arr, 27)) // Study
为了解决@ jfriend00的注释,以保持代码的可读性并防止不必要的额外数组创建,可以引入一个小的辅助函数。
在这一点上,我将其称为过早的优化。 除非您拥有大量数据集,否则原始代码很可能会满足您的需求。 如果您在代码上运行了探查器,并且注意到这段代码使您放慢了速度,那么可能是时候开始进行一些调整了……
const apush = (xs,x) => (xs.push(x), xs) const giveAdminTasks = (data, n) => data.reduce((acc, {adminTask, lessonNo}) => lessonNo === 3 ? apush(acc, adminTask) : acc, []).join(' + ') let arr = [ {adminTask: "Print Certificate",lessonNo: 0}, {adminTask: "Study",lessonNo: 27}, {adminTask: "Print Certificate",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3} ] console.log(giveAdminTasks(arr, 3)) // Print Certificate + Calling Record + Calling Record
我会使用filter
, map
和join
:
var arr = [{adminTask: "Print Certificate",lessonNo: 0}, {adminTask: "Study",lessonNo: 27}, {adminTask: "Print Certificate",lessonNo: 3}, {adminTask: "Calling Record",lessonNo: 3}, {adminTask:"Calling Record",lessonNo: 3}]; var item = arr.filter(function(elem){ return elem.lessonNo === 3; }).map(function(elem){ return elem.adminTask; }).join(' + '); console.log(item);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.