JavaScriptマップ関数が未定義を返すのはなぜですか?


112

私のコード

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

これにより、次の結果が得られます

["a","b",undefined]

結果の配列でundefinedを使用したくないのですが、どうすればよいですか?


3
文字列でなければ何も返さないからです。したがって、最後のアイテムはを返しますundefined。文字列でない場合、何を返すと思いますか?空の文字列?
BenM 2013

2
@BenM文字列でない場合、何も返さないようにします。未定義でもありません。
Akshat Jiwan Sharma

4
これを行うために間違った方法を使用していたようです。提案されているようにフィルターを使用します。
Akshat Jiwan Sharma

答えを受け入れることをお勧めします。
Ikke 2013

3
jQuery.mapは実際には、結果の配列に未定義の値やnull値を含めないように十分スマートです。
ドナルドテイラー

回答:


178

アイテムが文字列でない場合、何も返しません。その場合、関数は未定義の結果を返します。

map関数は、ある値を別の値にマップするために使用されますが、実際には配列をフィルタリングする必要があるようですが、map関数は適していません。

実際に必要なのはフィルター関数です。結果の配列にアイテムが必要かどうかに基づいてtrueまたはfalseを返す関数を受け取ります。

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

2
ああ...フィルター機能があるとは知りませんでした。
Akshat Jiwan Sharma

これはかなり理にかなっています。私は.mapしていませんでした.filterしていました...どのようにして知りましたか?!おかげで^。^
DigitalDesignDj

かなり論理的な感謝@Ikke
Malik Khalil、

回答を検索する手間を省きました。ありがとう。
ソフィーチャン

21

フィルターは、アイテムが変更されないこの特定のケースで機能します。しかし、多くの場合、マップを使用するとき、渡されたアイテムにいくつかの変更を加えたいと思います。

それがあなたの意図であるなら、あなたは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
}, [])

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

現在の要素がの場合にのみ値を返しますstring。おそらく空の文字列を割り当てるだけで十分です。

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

もちろん、文字列以外の要素をフィルタリングする場合は、を使用しないでくださいmap()。むしろ、filter()関数の使用を検討する必要があります。


3
これは、数値が存在する場合は空の文字列を返します
Prasath K

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

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']
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.