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?


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';  
});

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

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');

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

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.


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;}  
               });

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']
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.