Dlaczego funkcja mapy javascript zwraca wartość undefined?


115

Mój kod

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

Daje to następujące wyniki

["a","b",undefined]

Nie chcę, aby wartość undefined znajdowała się w tablicy wyników. Jak mogę to zrobić?


3
Ponieważ nic nie zwracasz, chyba że jest to ciąg. Dlatego wraca ostatnia pozycja undefined. Czego spodziewasz się zwrócić, jeśli nie jest to ciąg? Pusty ciąg?
BenM

2
@BenM, jeśli nie jest to ciąg, nie chcę, aby nic zwracano.
Akshat Jiwan Sharma,

4
Wygląda na to, że użyłem złej metody, aby to zrobić. Użyję filtra zgodnie z sugestią.
Akshat Jiwan Sharma

Możesz zaakceptować odpowiedź.
Ikke

3
jQuery.map jest wystarczająco inteligentny, aby nie uwzględniać niezdefiniowanych i zerowych wartości w wynikowej tablicy.
Donald Taylor

Odpowiedzi:


180

Nie zwracasz niczego w przypadku, gdy element nie jest ciągiem. W takim przypadku funkcja zwraca undefined, co widzisz w wyniku.

Funkcja map służy do mapowania jednej wartości na inną, ale wygląda na to, że w rzeczywistości chcesz filtrować tablicę, do czego funkcja mapowania nie jest odpowiednia.

To, czego naprawdę chcesz, to funkcja filtrująca . Pobiera funkcję, która zwraca prawdę lub fałsz w zależności od tego, czy chcesz, aby element znajdował się w wynikowej tablicy, czy nie.

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

2
Ahh ... Nie wiedziałem, że jest funkcja filtrująca, dzięki.
Akshat Jiwan Sharma

To ma sens. Nie .mapowałem. Filtowałem ... Skąd wiedziałeś ?! Oo, dzięki ^. ^
DigitalDesignDj

całkiem logiczne Dzięki @Ikke
Malik Khalil

Oszczędziłam wysiłków, by szukać odpowiedzi. Dzięki.
Sophie Zhang

22

Filtr działa w tym konkretnym przypadku, w którym elementy nie są modyfikowane. Jednak w wielu przypadkach, gdy używasz mapy, chcesz dokonać pewnych modyfikacji przekazanych elementów.

jeśli taki jest Twój zamiar, możesz użyć redukuj :

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
Dzięki - mapwyniki w tablicach z undefined. filtertylko zwraca przedmiot lub nie. to jest idealne
Zach Smith

15

Ponieważ ES6 filterobsługuje notację ze spiczastą strzałką (jak LINQ):

Można więc sprowadzić się do jednego liniowca.

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

10

Moim rozwiązaniem byłoby użycie filtra po mapie.

Powinno to obsługiwać każdy typ danych JS.

przykład:

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

Zwracasz wartość tylko wtedy, gdy bieżący element to string. Być może przypisanie pustego ciągu w przeciwnym razie wystarczy:

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

Oczywiście, jeśli chcesz filtrować elementy niebędące łańcuchami, nie powinieneś używać map(). Raczej powinieneś przyjrzeć się używaniu filter()funkcji.


3
Zwraca pusty ciąg, jeśli istnieje liczba
Prasath K

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

3

Możesz zaimplementować jak poniżej logikę. Załóżmy, że chcesz mieć tablicę wartości.

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']
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.