Mengapa fungsi peta javascript kembali tidak terdefinisi?

115

Kode saya

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

Ini memberikan hasil sebagai berikut

["a","b",undefined]

Saya tidak ingin undefined dalam larik hasil. Bagaimana cara melakukannya?

Akshat Jiwan Sharma
sumber
3
Karena Anda tidak mengembalikan apa pun kecuali itu string. Oleh karena itu, item terakhir kembali undefined. Apa yang Anda harapkan untuk dikembalikan jika itu bukan string? String kosong?
BenM
2
@BenM jika itu bukan string saya ingin tidak ada yang dikembalikan. Bahkan tidak ditentukan.
Akshat Jiwan Sharma
4
Sepertinya saya menggunakan metode yang salah untuk melakukan ini. Saya akan menggunakan filter seperti yang disarankan.
Akshat Jiwan Sharma
Anda mungkin ingin menerima jawaban.
Ikke
3
jQuery.map sebenarnya cukup pintar untuk tidak menyertakan nilai tidak terdefinisi dan null dalam larik yang dihasilkan.
Donald Taylor

Jawaban:

180

Anda tidak akan mengembalikan apa pun jika item tersebut bukan string. Dalam hal ini, fungsi mengembalikan tidak terdefinisi, apa yang Anda lihat di hasil.

Fungsi peta digunakan untuk memetakan satu nilai ke nilai lainnya, tetapi tampaknya Anda sebenarnya ingin memfilter larik, yang tidak cocok untuk fungsi peta.

Yang Anda inginkan sebenarnya adalah fungsi filter . Dibutuhkan fungsi yang mengembalikan benar atau salah berdasarkan apakah Anda menginginkan item dalam larik yang dihasilkan atau tidak.

var arr = ['a','b',1];
var results = arr.filter(function(item){
    return typeof item ==='string';  
});
Ikke
sumber
2
Ahh ... saya tidak tahu ada fungsi filter. Terima kasih.
Akshat Jiwan Sharma
Ini cukup masuk akal. Saya tidak .map'ing Saya .filter'ing ... Bagaimana Anda tahu ?! Oo Terima kasih ^. ^
DigitalDesignDj
cukup logis Terima kasih @Ikke
Malik Khalil
Menghemat usaha saya untuk mencari jawaban. Terima kasih.
Sophie Zhang
22

Filter berfungsi untuk kasus khusus ini di mana item tidak diubah. Tetapi dalam banyak kasus ketika Anda menggunakan peta Anda ingin membuat beberapa modifikasi pada item yang dikirimkan.

jika itu maksud Anda, Anda bisa menggunakan reduce :

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
sumber
1
Terima kasih - mapmenghasilkan array dengan undefined. filterhanya mengembalikan barang atau tidak. ini sempurna
Zach Smith
15

Karena ES6 filtermendukung notasi panah runcing (seperti LINQ):

Jadi itu bisa diringkas menjadi mengikuti satu baris.

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

Solusi saya adalah menggunakan filter setelah peta.

Ini harus mendukung setiap tipe data JS.

contoh:

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
sumber
8

Anda hanya mengembalikan nilai jika elemen saat ini adalah a string. Mungkin menugaskan string kosong jika tidak sudah cukup:

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

Tentu saja, jika Anda ingin memfilter elemen non-string apa pun, Anda tidak boleh menggunakan map(). Sebaliknya, Anda harus mempertimbangkan untuk menggunakan filter()fungsinya.

BenM
sumber
3
Ini mengembalikan string kosong jika ada nomor
Prasath K
5
var arr = ['a','b',1];
 var results = arr.filter(function(item){
                if(typeof item ==='string'){return item;}  
               });
Prasath K
sumber
3

Anda dapat mengimplementasikan seperti logika di bawah ini. Misalkan Anda menginginkan array nilai.

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
sumber