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.