Pourquoi la fonction de carte javascript retourne-t-elle undefined?


115

Mon code

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

Cela donne les résultats suivants

["a","b",undefined]

Je ne veux pas d'indéfini dans le tableau des résultats, comment puis-je le faire?


3
Parce que vous ne retournez rien à moins que ce ne soit une chaîne. Par conséquent, le dernier élément revient undefined. Qu'espérez-vous retourner si ce n'est pas une chaîne? Une chaîne vide?
BenM

2
@BenM si ce n'est pas une chaîne, je ne veux rien retourné, même pas indéfini.
Akshat Jiwan Sharma

4
Il semble que j'utilisais la mauvaise méthode pour le faire. J'utiliserai le filtre comme suggéré.
Akshat Jiwan Sharma

Vous voudrez peut-être accepter une réponse.
Ikke

3
jQuery.map est en fait assez intelligent pour ne pas inclure de valeurs non définies et nulles dans le tableau résultant.
Donald Taylor

Réponses:


181

Vous ne retournez rien dans le cas où l'élément n'est pas une chaîne. Dans ce cas, la fonction renvoie undefined, ce que vous voyez dans le résultat.

La fonction de mappage est utilisée pour mapper une valeur à une autre, mais il semble que vous voulez réellement filtrer le tableau, ce à quoi une fonction de mappage ne convient pas.

Ce que vous voulez réellement, c'est une fonction de filtrage . Il prend une fonction qui renvoie vrai ou faux selon que vous voulez ou non l'élément dans le tableau résultant.

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

2
Ahh ... Je ne savais pas qu'il y avait une fonction de filtrage. Merci.
Akshat Jiwan Sharma

Cela a beaucoup de sens. Je ne faisais pas de mappage, je filtrais ... Comment le saviez-vous?! Oo Merci ^. ^
DigitalDesignDj

tout à fait logique Merci @Ikke
Malik Khalil

J'ai épargné mes efforts pour rechercher une réponse. Merci.
Sophie Zhang

22

Le filtre fonctionne pour ce cas spécifique où les éléments ne sont pas modifiés. Mais dans de nombreux cas, lorsque vous utilisez map, vous souhaitez apporter des modifications aux éléments transmis.

si tel est votre intention, vous pouvez utiliser réduire :

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
Merci - maprésultats dans des tableaux avec undefined. filterne renvoie que l'article ou non. c'est parfait
Zach Smith

15

Depuis ES6 filterprend en charge la notation de flèche pointue (comme LINQ):

Ainsi, il peut être réduit à une seule ligne suivante.

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

10

Ma solution serait d'utiliser le filtre après la carte.

Cela devrait prendre en charge tous les types de données JS.

exemple:

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

Vous ne renvoyez une valeur que si l'élément actuel est un string. Peut-être que l'assignation d'une chaîne vide suffira autrement:

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

Bien sûr, si vous souhaitez filtrer des éléments non-string, vous ne devez pas utiliser map(). Vous devriez plutôt vous pencher sur l'utilisation de la filter()fonction.


3
Cela renvoie une chaîne vide s'il existe un nombre
Prasath K

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

3

Vous pouvez implémenter comme une logique ci-dessous. Supposons que vous vouliez un tableau de valeurs.

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']
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.