JavaScript 入門 | 配列 (array) | 配列の活用

疎配列

疎配列とは、配列に属する要素の位置が連続していない配列を意味する。
したがって疎配列の場合、配列の length プロパティの値よりも配列要素の数は常に少ない。

var arr = new Array(); // 空の配列オブジェクトを作成する。
arr[99] = "JavaScript" // 配列 arr の 100 番目の位置に文字列を挿入する。
// 100 番目の要素を挿入したため、配列の長さは 100 に増える。
document.write("配列の長さは " + arr.length + " である。");

多次元配列

多次元配列とは、配列要素がさらに別の配列である配列を意味する。

  • これまで見てきた配列は 1 次元配列である。
  • 2 次元配列とは、配列要素が 1 次元配列である配列を意味する。
  • 3 次元配列とは、配列要素が 2 次元配列である配列を意味する。

2 次元配列を理解すれば、それ以上の配列も同じ方式で理解できる。

var arr = new Array(3);      // 3 つの要素を持つ配列を作成する。
for (var row = 0; row < 3; row++) {
    arr[row] = new Array(4); // それぞれの要素ごとに、さらに 4 つの要素を持つ配列を作成する。
    for (var column = 0; column < 4; column++) {
        arr[row][column] = "[" + row + "," + column + "]"; // それぞれの配列要素を作成する。
        document.write(arr[row][column] + " ");            // 各配列要素にアクセスする。
    }
}

2 次元配列の配列要素は、[] 演算子を 2 回使用して参照できる。

連想配列 (associative array)

JavaScript で配列のインデックスには、0 を含む正の整数だけを使用できる。
このように数値のインデックスの代わりに文字列のキー (key) を使用する配列を連想配列 (associative array) という。

多くのプログラミング言語がサポートする連想配列を、JavaScript は別途提供していない。
代わりに、インデックスとして文字列を使用し、連想配列のように扱えるオブジェクト (object) を作成できる。

しかし、このように作成された配列は、JavaScript 内部で Array オブジェクトから基本オブジェクトへ再宣言される。
したがって、これまで使用できたすべての Array メソッドとプロパティは、正確ではない結果値を返すことになる。

var arr = [];     // 空の配列を作成する。
arr["one"] = 1;   // 数値インデックスの代わりに文字列をインデックスとして配列要素を追加する。
arr["true"] = true;
arr["JavaScript"] = "JavaScript";
document.write(arr["true"]); // 文字列をインデックスとして配列要素にアクセスできる。
document.write(arr.length);  // 連想配列は Array オブジェクトではないため、length プロパティの値は 0 である。
document.write(arr[0]);      // undefined

上の例で、連想配列である arr は length プロパティの値として 0 を返す。
このように JavaScript で連想配列は Array オブジェクトではなく基本オブジェクトなので、正確には配列ではない。

ECMAScript 6 からは、この不便さを解決するために、新しいデータ構造である Map オブジェクトが別途提供されている。

文字列を配列のようにアクセスする

JavaScript で文字列は変化しない値なので、読み取り専用配列として扱うことができる。

したがって、配列のように [] 演算子を使用して、文字列を構成する各文字へ直接アクセスできる。
また、Array オブジェクトが提供するすべての汎用メソッドも使用できる。
文字列の各文字は、String オブジェクトが提供する charAt() メソッドを使ってもアクセスできる。

var str = "こんにちは!";       // 文字列の作成
document.write(str.charAt(2)); // に
document.write(str[2]);        // に

しかし、このように文字列を配列のようにアクセスする方法は、Internet Explorer 7 以前のバージョンでは動作しない。 また、文字列を配列のように誤解させ、次のようなミスを誘発することもある。

var str = "こんにちは!"; // 文字列の作成
str[0] = "";             // JavaScript の文字列は読み取り専用なので、この文はエラーを発生させる。

したがって、文字列をそのまま配列のように使用せず、split() メソッドなどを利用して先に配列へ変換してから使用するのがよい。

JavaScript で配列かどうかを確認する

JavaScript では、配列という型 (type) を別途提供していない。 JavaScript の配列は object 型になり、typeof 演算子を使用すると ‘object’ を返す。

var arr = [1, true, "JavaScript"]; // 配列の作成
document.write(typeof arr);        // object

したがって JavaScript では、該当する変数が配列かどうかを確認できるよう、次のような方法を提供している。

  1. Array.isArray() メソッド
  2. instanceof 演算子
  3. constructor プロパティ

ECMAScript 5 からは、Array クラスに isArray() という配列かどうかを確認できるメソッドが追加された。

document.write(Array.isArray(arr));      // true
document.write(Array.isArray("文字列")); // false

しかし古いバージョンのブラウザーは ECMAScript 5 をサポートしていないため、Array.isArray() メソッドが正常に動作しないこともある。
そのため、この場合は instanceof 演算子を使用して、その変数が Array オブジェクトかどうかを判断し、配列かどうかを確認できる。

document.write(arr instanceof Array); // true
document.write(123 instanceof Array); // false

また、Array オブジェクトの constructor プロパティを使用して、配列かどうかを確認することもできる。 JavaScript 配列に対して constructor プロパティは次のような値を返す。

構文

function Array() {[native code]}

したがって、次の例のように toString() メソッドと indexOf() メソッドを一緒に使用すると、その変数が配列かどうかを確認できる。

function isArray(a) {
    return a.constructor.toString().indexOf("Array") > -1;
}

var arr = [1, true, "JavaScript"];          // 配列の作成
document.write(arr.constructor);            // constructor プロパティの値を出力
document.write(arr.constructor.toString()); // function Array() {[native code]}
document.write(arr.constructor.toString().indexOf("Array")); // 10
document.write(isArray(arr))                // true

上の例の ② 番ラインでは、toString() メソッドを使用して constructor プロパティの値を文字列へ変換する。
そして ③ 番ラインでは、indexOf() メソッドを使用して、その文字列から “Array” という部分文字列が始まるインデックスを求めている。
indexOf() メソッドは、引数として渡された文字列を対象の文字列から見つけられない場合、常に -1 を返す。
したがって、もし変数 arr が配列であれば “Array” という部分文字列を常に含むため、① 番ラインの結果は常に true を返す。