Why does JavaScript map function return undefined?
JavascriptJavascript Problem Overview
My code
var arr = ['a','b',1];
var results = arr.map(function(item){
if(typeof item ==='string'){return item;}
});
This gives the following results
["a","b",undefined]
I don't want undefined
in the results array. How can I do it?
Javascript Solutions
Solution 1 - Javascript
You aren't returning anything in the case that the item is not a string. In that case, the function returns undefined
, what you are seeing in the result.
The map function is used to map one value to another, but it looks like you actually want to filter the array, which a map function is not suitable for.
What you actually want is a filter function. It takes a function that returns true or false based on whether you want the item in the resulting array or not.
var arr = ['a','b',1];
var results = arr.filter(function(item){
return typeof item ==='string';
});
Solution 2 - Javascript
Filter works for this specific case where the items are not modified. But in many cases when you use map you want to make some modification to the items passed.
if that is your intent, you can use 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
}, [])
Solution 3 - Javascript
Since ES6 filter
supports pointy arrow notation (like LINQ):
So it can be boiled down to following one-liner.
['a','b',1].filter(item => typeof item ==='string');
Solution 4 - Javascript
My solution would be to use filter after the map.
This should support every JS data type.
example:
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
Solution 5 - Javascript
You can implement like a below logic. Suppose you want an array of values.
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']
Solution 6 - Javascript
You only return a value if the current element is a string
. Perhaps assigning an empty string otherwise will suffice:
var arr = ['a','b',1];
var results = arr.map(function(item){
return (typeof item ==='string') ? item : '';
});
Of course, if you want to filter any non-string elements, you shouldn't use map()
. Rather, you should look into using the filter()
function.
Solution 7 - Javascript
var arr = ['a','b',1];
var results = arr.filter(function(item){
if (typeof item ==='string') {return item;}
});
Solution 8 - Javascript
If you have to use map to return custom output, you can still combine it with filter.
const arr = ['a','b',1]
const result = arr.map(element => {
if(typeof element === 'string')
return element + ' something'
}).filter(Boolean) // this will filter out null and undefined
console.log(result) // output: ['a something', 'b something']
Solution 9 - Javascript
If you use it like this, your problem will be solved. Also, you will have a clean and short code
var _ = require('lodash'); //but first, npm i lodash --save
var arr = ['a','b',1];
var results = _.compact(
_.map(arr, function(item){
if(_.isString(item)){return item;}
}
); //false, null, undefined ... etc will not be included
with ES6...
const _ = require('lodash'); //but first, npm i lodash --save
const arr = ['a','b',1];
const results = _.compact(
_.map(arr, item => {
if(_.isString(item)){return item;}
}
);