繁体   English   中英

为什么Javascript .map()返回并且为字符串对象额外的“未定义”?

[英]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 

我会使用filtermapjoin

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM