Por que a função de mapa javascript retorna indefinida?


112

Meu código

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

Isso dá os seguintes resultados

["a","b",undefined]

Não quero indefinido na matriz de resultados. Como posso fazer isso?


3
Porque você não retorna nada a menos que seja uma string. Portanto, o último item retorna undefined. O que você espera retornar se não for uma string? Uma string vazia?
BenM de

2
@BenM se não for uma string, não quero que nada seja retornado. Nem mesmo indefinido.
Akshat Jiwan Sharma

4
Parece que estava usando o método errado para fazer isso. Usarei o filtro conforme sugerido.
Akshat Jiwan Sharma

Você pode querer aceitar uma resposta.
Ikke de

3
jQuery.map é realmente inteligente o suficiente para não incluir valores indefinidos e nulos no array resultante.
Donald Taylor

Respostas:


178

Você não está retornando nada no caso de o item não ser uma string. Nesse caso, a função retorna indefinido, o que você está vendo no resultado.

A função de mapa é usada para mapear um valor para outro, mas parece que você realmente deseja filtrar a matriz, para a qual uma função de mapa não é adequada.

O que você realmente quer é uma função de filtro . Leva uma função que retorna verdadeiro ou falso com base em se você deseja ou não o item na matriz resultante.

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

2
Ahh ... eu não sabia que existia uma função de filtro.Obrigado.
Akshat Jiwan Sharma

Isso faz bastante sentido. Eu não estava .mapeando, estava .filtrando ... Como você sabia ?! Oo Obrigado ^. ^
DigitalDesignDj

bastante lógico Obrigado @Ikke
Malik Khalil

Economizei meu esforço para procurar uma resposta. Obrigado.
Sophie Zhang,

21

O filtro funciona para este caso específico em que os itens não são modificados. Mas em muitos casos, ao usar o mapa, você deseja fazer algumas modificações nos itens passados.

se essa for sua intenção, você pode usar reduzir :

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
}, [])

1
Obrigado - mapresulta em matrizes com undefined. filterapenas retorna o item ou não. isso é perfeito
Zach Smith

15

Uma vez que ES6 filtersuporta notação de seta pontiaguda (como LINQ):

Portanto, pode ser resumido a seguir uma linha.

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

10

Minha solução seria usar o filtro após o mapa.

Isso deve suportar todos os tipos de dados JS.

exemplo:

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

8

Você só retorna um valor se o elemento atual for um string. Talvez atribuir uma string vazia seja suficiente:

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

Claro, se você quiser filtrar quaisquer elementos que não sejam string, você não deve usar map(). Em vez disso, você deve tentar usar a filter()função.


3
Isso retorna uma string vazia se houver um número
Prasath K de

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

2

Você pode implementar como uma lógica abaixo. Suponha que você queira uma matriz de valores.

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']
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.