Warum gibt die JavaScript-Kartenfunktion undefiniert zurück?

112

Mein Code

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

Dies ergibt die folgenden Ergebnisse

["a","b",undefined]

Ich möchte nicht undefiniert im Ergebnisarray. Wie kann ich das tun?

Akshat Jiwan Sharma
quelle
3
Weil Sie nichts zurückgeben, es sei denn, es ist eine Zeichenfolge. Daher wird der letzte Artikel zurückgegeben undefined. Was erwarten Sie, wenn es sich nicht um eine Zeichenfolge handelt? Eine leere Zeichenfolge?
BenM
2
@BenM Wenn es kein String ist, möchte ich nichts zurückgeben. Nicht einmal undefiniert.
Akshat Jiwan Sharma
4
Sieht so aus, als hätte ich die falsche Methode verwendet. Ich werde den Filter wie vorgeschlagen verwenden.
Akshat Jiwan Sharma
Vielleicht möchten Sie eine Antwort akzeptieren.
Ikke
3
jQuery.map ist tatsächlich intelligent genug, um keine undefinierten und Nullwerte in das resultierende Array aufzunehmen.
Donald Taylor

Antworten:

178

Sie geben nichts zurück, falls das Element keine Zeichenfolge ist. In diesem Fall gibt die Funktion undefiniert zurück, was Sie im Ergebnis sehen.

Die Zuordnungsfunktion wird verwendet, um einen Wert einem anderen zuzuordnen, aber es sieht so aus, als ob Sie das Array tatsächlich filtern möchten, für das eine Zuordnungsfunktion nicht geeignet ist.

Was Sie eigentlich wollen, ist eine Filterfunktion . Es wird eine Funktion verwendet, die true oder false zurückgibt, je nachdem, ob das Element im resultierenden Array enthalten sein soll oder nicht.

var arr = ['a','b',1];
var results = arr.filter(function(item){
    return typeof item ==='string';  
});
Ikke
quelle
2
Ahh ... ich wusste nicht, dass es eine Filterfunktion gibt. Danke.
Akshat Jiwan Sharma
Das macht ziemlich viel Sinn. Ich habe nicht abgebildet Ich habe gefiltert ... Woher wusstest du das?! Oo Danke ^. ^
DigitalDesignDj
ganz logisch Danke @Ikke
Malik Khalil
Ersparte mir die Suche nach einer Antwort. Vielen Dank.
Sophie Zhang
21

Der Filter funktioniert für diesen speziellen Fall, in dem die Elemente nicht geändert werden. In vielen Fällen möchten Sie jedoch bei Verwendung der Karte Änderungen an den übergebenen Elementen vornehmen.

Wenn dies Ihre Absicht ist, können Sie reduzieren verwenden :

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
}, [])
Nicola Pedretti
quelle
1
Danke - mapergibt Arrays mit undefined. filtergibt nur den Artikel zurück oder nicht. das ist perfekt
Zach Smith
15

Da ES6 filterdie Notation mit spitzen Pfeilen unterstützt (wie LINQ):

So kann es auf folgenden Einzeiler reduziert werden.

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

Meine Lösung wäre, Filter nach der Karte zu verwenden.

Dies sollte jeden JS-Datentyp unterstützen.

Beispiel:

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
Jojo Narte
quelle
8

Sie geben nur dann einen Wert zurück, wenn das aktuelle Element a ist string. Vielleicht reicht es aus, ansonsten eine leere Zeichenfolge zuzuweisen:

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

Wenn Sie Elemente ohne Zeichenfolge filtern möchten, sollten Sie diese natürlich nicht verwenden map(). Sie sollten sich vielmehr mit der Verwendung der filter()Funktion befassen.

BenM
quelle
3
Dies gibt eine leere Zeichenfolge zurück, wenn eine Zahl vorhanden ist
Prasath K
5
var arr = ['a','b',1];
 var results = arr.filter(function(item){
                if(typeof item ==='string'){return item;}  
               });
Prasath K.
quelle
2

Sie können wie folgt implementieren. Angenommen, Sie möchten ein Array von Werten.

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']
mkumar
quelle