Чому функція карти javascript повертається невизначеною?


114

Мій код

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

Це дає такі результати

["a","b",undefined]

Я не хочу визначитись у масиві результатів. Як це зробити?


3
Тому що ви нічого не повертаєте, якщо це не рядок. Тому останній пункт повертається undefined. Що ви очікуєте повернути, якщо це не рядок? Порожній рядок?
БенМ

2
@BenM, якщо це не рядок, я хочу, щоб нічого не повернулося. Навіть не визначено.
Akshat Jiwan Sharma

4
Схоже, я використовував неправильний метод для цього. Я буду використовувати фільтр, як було запропоновано.
Akshat Jiwan Sharma

Ви можете прийняти відповідь.
Іке

3
jQuery.map насправді досить розумний, щоб не включати невизначені та нульові значення в отриманий масив.
Дональд Тейлор

Відповіді:


179

Ви нічого не повертаєте, якщо елемент не є рядком. У цьому випадку функція повертається невизначено, що ви бачите в результаті.

Функція map використовується для зіставлення одного значення іншому, але, схоже, ви хочете фільтрувати масив, для якого функція карти не підходить.

Те, що ви насправді хочете, - це функція фільтра . Потрібна функція, яка повертає true чи false, залежно від того, хочете ви елемент у масиві, що виходить, чи ні.

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

2
Ааа ... я не знав, що є функція фільтра. Дякую.
Akshat Jiwan Sharma

Це має досить багато сенсу. Я не був. Карти, я був. Фільтруванням ... Звідки ти знав ?! Oo Спасибі ^. ^
DigitalDesignDj

цілком логічна подяка @Ikke
Malik Khalil

Врятував мої зусилля на пошук відповіді. Дякую.
Софі Чжан

22

Фільтр працює для цього конкретного випадку, коли елементи не змінюються. Але в багатьох випадках, коли ви використовуєте карту, ви хочете внести деякі зміни до переданих елементів.

якщо це ваш намір, ви можете скористатися скороченням :

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
Спасибі - mapрезультати в масивах з undefined. filterповертає лише товар або ні. це ідеально
Зак Сміт

15

Оскільки ES6 filterпідтримує точкові позначення стрілок (як LINQ):

Таким чином, це може бути зведено до наступного однолінійного.

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

10

Моє рішення - використовувати фільтр після карти.

Це повинно підтримувати кожен тип даних JS.

приклад:

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

Ви повертаєте значення лише у тому випадку, якщо поточним елементом є a string. Можливо, присвоєння порожнього рядка інакше буде достатньо:

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

Звичайно, якщо ви хочете відфільтрувати будь-які не струнні елементи, ви не повинні використовувати map(). Швидше, вам слід розглянути використання filter()функції.


3
Це повертає порожній рядок, якщо існує число
Prasath K


2

Ви можете реалізовувати подібну нижче логіку. Припустимо, ви хочете масив значень.

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']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.