Help us understand the problem. What is going on with this article?

JavaScript で文字列の配列を数値の配列にしたい

More than 1 year has passed since last update.

文字列の配列 ['1', '2', '3'] の各要素を Array.map() で変換して、数値の配列 [1, 2, 3] にしたい。

失敗例

['1', '2', '3'].map(parseInt);

上記の戻り値は、 [1, NaN, NaN] になってしまう。原因は後述。

結論

小数や指数を含んでもよい場合

['1', '2', '3'].map(Number);

int限定の場合

['1', '2', '3'].map( str => parseInt(str, 10) );

参考

parseInt() のドキュメント
Array.map() のドキュメント (「トリッキーな使用例」の項)
上記のインスパイア元のブログ

以下は、参考ページの内容を自分なりに解釈・要約したものです。
正確な内容は上記ページをご参照ください。

parseInt ではだめな理由

前提1 Array.map()の仕様

構文

var new_array = arr.map(function callback(currentValue[, index[, array]]) {} )

引数

  • callback: 新しい配列の要素を生成するための関数。次の3つの引数を取る。
    • currentValue: 現在処理中の要素の値。
    • index: 現在処理中の要素の配列内におけるインデックス。
    • array: map が実行されている配列。

戻り値

与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列。

前提2 parseInt() の仕様

構文

parseInt(string, radix);

引数

  • string: 解析する値。引数stringが文字列でなければ、(抽象操作ToStringにより)文字列に変換される。
  • radix: 2から36までの整数で、前述の文字列に対する基数(数学的記数法の底)を与える。基数が与えられない場合、通常は10。

戻り値

与えられた文字列を解析した整数値。最初の文字を数値に変換できない場合、NaN が返される。

つまり?

['1', '2', '3'].map(parseInt);

上記のように記述してしまうと、実際の parseInt() の呼び出しは下記のようになる。

parseInt("1", 0); // 第2引数はデフォルトの10になる※
parseInt("2", 1); // 1が基数として渡されるためNaNが返る
parseInt("3", 2); // 2が基数として渡され、"3"は2進数として解析できないためNaNが返る

parseInt() のドキュメントより、第2引数が0のときの基数は10とは限らない。

第2引数のradixがundefinedか0の(または与えられていない)場合は、JavaScriptはつぎのように解釈します。

  • 第1引数のstringが「0x」または「0X」で始まるときは、第2引数のradixは16(16進法)としてその後の文字列を解析します。
  • 第1引数のstringが「0」で始まるときは、第2引数のradixは8(8進法)または10(10進法)とされます。厳密には、基数がどちらになるかは実装によります。ECMAScript 5 の仕様では10(10進法)です。ただし、まだすべてのブラウザがサポートしている訳ではありません。したがって、parseInt()関数を使うとき基数は必ず与えてください。
  • 第1引数のstringがその他の値で始まるときは、第2引数のradixは10(10進法)とされます。

(蛇足)配列の値によっては下記のようになる。

["0XFF","2","10"].map(parseInt); // 戻り値は [255, NaN, 2]( 16進数、NaN、2進数)

parseIntを使うなら

ファンクションを別途定義する。

function returnInt(element) {
  return parseInt(element, 10); // 第二引数を明示する
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]

アロー関数を使うと短く書ける。

['1', '2', '3'].map( str => parseInt(str, 10) ); // [1, 2, 3]

渡す値が決まっているならNumberオブジェクトを使うのが一番簡潔。

['1', '2', '3'].map(Number); // [1, 2, 3]

// 小数表現や指数表現も解釈できる(してしまう)
['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away