繁体   English   中英

为什么 JavaScript map function 返回未定义?

[英]Why does JavaScript map function return undefined?

我的代码

 var arr = ['a','b',1];
 var results = arr.map(function(item){
                if(typeof item ==='string'){return item;}  
               });

这给出了以下结果

["a","b",undefined]

我不想在结果数组中undefined 我该怎么做?

如果项目不是字符串,您不会返回任何内容。 在这种情况下,该函数返回undefined ,即您在结果中看到的内容。

map 函数用于将一个值映射到另一个值,但看起来您实际上想要过滤数组,而 map 函数不适合这种情况。

你真正想要的是一个过滤功能。 它需要一个函数,根据您是否想要结果数组中的项目返回 true 或 false。

var arr = ['a','b',1];
var results = arr.filter(function(item){
    return typeof item ==='string';  
});

过滤器适用于不修改项目的这种特定情况。 但是在很多情况下,当您使用 map 时,您希望对传递的项目进行一些修改。

如果这是您的意图,您可以使用reduce

var arr = ['a','b',1];
var results = arr.reduce((results, item) => {
    if (typeof item === 'string') results.push(modify(item)) // modify is a fictitious function that would apply some change to the items in the array
    return results
}, [])

由于 ES6 filter支持尖箭头符号(如 LINQ):

所以它可以归结为以下单行。

['a','b',1].filter(item => typeof item ==='string');

我的解决方案是在地图后使用过滤器。

这应该支持每种 JS 数据类型。

例子:

const notUndefined = anyValue => typeof anyValue !== 'undefined'    
const noUndefinedList = someList
          .map(// mapping condition)
          .filter(notUndefined); // by doing this, 
                      //you can ensure what's returned is not undefined

您可以实现如下逻辑。 假设您想要一个值数组。

let test = [ {name:'test',lastname:'kumar',age:30},
             {name:'test',lastname:'kumar',age:30},
             {name:'test3',lastname:'kumar',age:47},
             {name:'test',lastname:'kumar',age:28},
             {name:'test4',lastname:'kumar',age:30},
             {name:'test',lastname:'kumar',age:29}]

let result1 = test.map(element => 
              { 
                 if (element.age === 30) 
                 {
                    return element.lastname;
                 }
              }).filter(notUndefined => notUndefined !== undefined);

output : ['kumar','kumar','kumar']

如果当前元素是string则仅返回一个值。 也许分配一个空字符串就足够了:

var arr = ['a','b',1];
var results = arr.map(function(item){
    return (typeof item ==='string') ? item : '';  
});

当然,如果要过滤任何非字符串元素,则不应使用map() 相反,您应该考虑使用filter()函数。

var arr = ['a','b',1];
 var results = arr.filter(function(item){
                if(typeof item ==='string'){return item;}  
               });

如果您必须使用 map 返回自定义输出,您仍然可以将其与 filter 结合使用。

const arr = ['a','b',1]

const result = arr.map(element => {

  if(typeof element === 'string')
    return element + ' something'

}).filter(Boolean) // this will filter out null and undefined

console.log(result) // output: ['a something', 'b something']

如果你这样使用它,你的问题将得到解决。 此外,您将拥有一个干净而简短的代码

var _ = require('lodash'); //but first, npm i lodash --save
var arr = ['a','b',1];
var results = _.compact(
    _.map(arr, function(item){
        if(_.isString(item)){return item;}
    }
); //false, null, undefined ... etc will not be included

使用 ES6...

const _ = require('lodash'); //but first, npm i lodash --save
const arr = ['a','b',1];
const results = _.compact(
    _.map(arr, item => {
        if(_.isString(item)){return item;}
    }
);

我经常遇到这种情况,过滤后的类型仍然是string | number string | number 因此,要扩展这些解决方案并包括类型安全,您可以使用用户定义的类型保护。 https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates

const result = ['a','b',1].filter((item) => typeof item ==='string');
// result is typed as (string | number)[]

使用用户定义的类型保护更好的类型安全

const result = ['a','b',1].filter((item): item is string => typeof item ==='string');
// result is now typed as string[]

问题:问题是arr.map()将对arr数组长度进行完整迭代,即map()方法将循环arr的长度,无论你在其中有什么条件,所以如果你定义其中的一个条件,例如if(typeof item ==='string'){return item;}即使条件没有发生, map()也会被迫继续循环,直到完成整个arr的循环,所以它会如果不满足条件,则为元素的 rest 提供undefined

解决方案:

解决方案一:如果你想在满足条件时返回数组中的整个项目,你可以使用arr.filter()这样过滤器将返回整个项目进行迭代,例如,如果你有像波纹管这样的对象数组

const arr = [{name: "Name1", age: 25}, {name: "Name2", age: 30}, {name: "Name3", age: 25}]

并且您想在满足条件时返回整个对象,如下例所示

const filteredItems = arr.filter((item)=>{if(item.age === 25){return true}})

console.log(filteredItems) //results: [{name: "Name1", age: 25}, {name: "Name3", age: 25}]

结论:如果满足条件, filter()方法将返回其中所有项目的数组。

解决方案二:如果您只想返回数组中对象的特定数据(或整个 object 或任何形状的数据),即如果您只想返回数组中的名称而不返回年龄,您可以这样做

const namesOnly = arr.map((item)=>{if(item.age === 25){return item.name}})

console.log(namesOnly) //results: ["Name1, udefined, "Name3"]

现在要删除undefined的,您只需对结果使用filter()方法,如下所示

const namesOnly = arr.map((item)=>{if(item.age === 25){return item.name}}).filter((item)=> !!item)

console.log(namesOnly) //results: ["Name1, "Name3"]

结论: map()方法在return中返回一个具体定义数据的数组,不满足条件则返回undefined 那么我们就可以使用filter()方法来删除undefined

您可以使用以下示例代码轻松地使用.map过滤记录

const datapoints = [
    {
        PL_STATUS: 'Packetloss',
        inner_outerx: 'INNER',
        KPI_PL: '97.9619'
    },
    {
        PL_STATUS: 'Packetloss',
        inner_outerx: 'OUTER',
        KPI_PL: '98.4621',
    },
    {
        PL_STATUS: 'Packetloss',
        inner_outerx: 'INNER',
        KPI_PL: '97.8770',
    },
    {
        PL_STATUS: 'Packetloss',
        inner_outerx: 'OUTER',
        KPI_PL: '97.5674',

    },
    {
        PL_STATUS: 'Packetloss',
        inner_outerx: 'INNER',
        KPI_PL: '98.7150',
    },
    {
        PL_STATUS: 'Packetloss',
        inner_outerx: 'OUTER',
        KPI_PL: '98.8969'
    }
];
const kpi_packetloss_inner: string[] = [];
datapoints.map((item: { PL_STATUS: string; inner_outerx: string; KPI_PL: string }) => {
    if (item.PL_STATUS === 'Packetloss' && item.inner_outerx === 'INNER') {
        kpi_packetloss_inner.push(item.KPI_PL);
    }
})
console.log(kpi_packetloss_inner);

Map 用于从原始数组生成新的修改后的数组。 简单的答案可能适用于某人

      var arr = ['a','b',1];
      var results = arr.filter(function(item){
      // Modify your original array here
     return typeof item ==='string';  
     }).filter(a => a);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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