Почему функция карты javascript возвращает значение undefined?


116

Мой код

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

Это дает следующие результаты

["a","b",undefined]

Я не хочу, чтобы в массиве результатов содержалось значение undefined, как это сделать?


3
Потому что вы ничего не возвращаете, кроме строки. Следовательно, возвращается последний элемент undefined. Что вы ожидаете вернуть, если это не строка? Пустая строка?
— BenM

2
@BenM, если это не строка, я не хочу ничего возвращать, даже не неопределенного.
— Акшат Дживан Шарма

4
Похоже, я использовал неправильный метод для этого. Я буду использовать фильтр, как было предложено.
— Акшат Дживан Шарма

Возможно, вы захотите принять ответ.
— Ikke

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

Ответы:


181

Вы ничего не возвращаете, если элемент не является строкой. В этом случае функция возвращает undefined, что вы видите в результате.

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

На самом деле вам нужна функция фильтра . Требуется функция, которая возвращает истину или ложь в зависимости от того, нужен ли вам элемент в результирующем массиве или нет.

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

2
Ааа ... Не знал, что есть функция фильтра. Спасибо.
— Акшат Дживан Шарма

В этом есть некоторый смысл. Я не .map'ing, я .filter'ing ... Откуда вы знаете ?! Оо Спасибо ^. ^
— DigitalDesignDj

вполне логично Спасибо @Ikke
— Малик Халил

Сэкономил мои усилия на поиск ответа. Спасибо.
— Софи Чжан

24

Фильтр работает для этого конкретного случая, когда элементы не изменяются. Но во многих случаях, когда вы используете карту, вы хотите внести некоторые изменения в переданные элементы.

если это ваше намерение, вы можете использовать сокращение :

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

11

Моим решением было бы использовать фильтр после карты.

Это должно поддерживать все типы данных 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

Вы возвращаете значение, только если текущий элемент - это string. Возможно, в противном случае будет достаточно присвоения пустой строки:

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

Конечно, если вы хотите отфильтровать любые нестроковые элементы, вам не следует использовать map(). Скорее вам следует изучить возможность использования filter()функции.


3
Это возвращает пустую строку, если существует число
— Прасат К.


3

Вы можете реализовать следующую логику. Предположим, вам нужен массив значений.

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.