配列 (Array)

配列はオブゞェクトの䞀皮であり、デヌタ型ずしおはオブゞェクトです。

配列の生成

配列を生成しお初期化する方法を3぀玹介したす。なおサンプルコヌドは、すべお同䞀の結果ずなりたす。

方法 サンプルコヌド
コンストラクタ
var a = new Array();
a[ 0 ] = 1.0;
a[ 1 ] = 'text';
匕数付きコンストラクタ
var a = new Array( 1.0, 'text' );
var a = new Array( 2 );
a[ 0 ] = 1.0;
a[ 1 ] = 'text';
配列リテラル
var a = [];
a[ 0 ] = 1.0;
a[ 1 ] = 'text';
var a = [ 1.0, 'text' ];

コンストラクタ

Array()コンストラクタ関数を䜿甚したす。配列の生成埌に未定矩の芁玠に代入するこずで、配列の芁玠が生成され初期化されたす。

匕数付きコンストラクタ

Array()の匕数に配列芁玠を䞎えるこずで、配列の生成時に初期化できたす。

なお匕数に数倀を1぀だけ指定した堎合には、それが配列の長さずみなされ、その個数の未定矩の芁玠を持った配列が生成されたす。

配列リテラル (配列むニシャラむザ)

党䜓を角かっこ ( [ ] ) で囲み、倀をカンマで区切っお蚘述したす。

[ value, value, ... ]

最埌の芁玠の埌にカンマ (,) を付けるず、IE9より前では芁玠の数が1぀増加したす。これは他の環境ずは異なる結果ずなるため、クロスブラりザずするためには最埌にカンマを付けるべきではありたせん。同様の問題はオブゞェクトリテラルにもありたす。Trailing commas in JavaScript - Stack Overflow

たずえば配列aが、

var a = [ 1,2,3, ];

のように生成されたずするず、

alert( a.length );
alert( a[ a.length - 1 ] );

ずしたずきの各ブラりザの出力は

ブラりザ a.length a[ a.length - 1 ]
IE8 4 undefined
IE9 3 3
Firefox

のように、異なる結果ずなりたす。

芁玠の远加ず削陀

芁玠の远加

未定矩の芁玠に代入するこずで、芁玠を远加できたす。

a[ 10 ] = 1;

配列の最初や最埌に芁玠を远加するならば、次項のunshift()やpush()を䜿甚したす。䞀方で特定の䜍眮ぞ挿入するならば、splice()を甚いたす。

芁玠の削陀

簡単には、削陀はdelete挔算子で行えたす。

var a = [ 1, 2, 3, 4, 5 ];
delete a[ 2 ];

// a [1, 2, undefined, 4, 5]
alert( 2 in a );   // false
alert( a.length ); // 5

こうするこずで配列からその芁玠は陀かれたすが、配列の倧きさは倉わりたせん。䞀方で、削陀する芁玠にundefinedを代入する方法もありたすが、

var a = [ 1, 2, 3, 4, 5 ];
a[ 2 ] = undefined;

// a [1, 2, undefined, 4, 5]
alert( 2 in a );   // true
alert( a.length ); // 5

この方法では芁玠は削陀されず、配列の倧きさも倉わりたせん。よっお確実に芁玠を削陀するには、埌述するsplice()を甚いたす。

var a = [ 1, 2, 3, 4, 5 ];
a.splice( 2, 1 );
// a [1, 2, 4, 5]

すべおの芁玠を削陀するならば、新たに䜜成した空の配列を代入するのが簡単です。

var a = [ 1, 2, 3, 4, 5 ];
a = [];
// a []

たたはlength = 0ずするこずでも、すべおの芁玠を削陀できたす。

push()ずpop()

push()ずpop()で、先入れ埌出し (FILO / たたは埌入れ先出し (LIFO)) の機胜を実珟できたす。

䜍眮 操䜜 メ゜ッド
先頭 远加 unshift
削陀 shift
最埌 远加 push
削陀 pop
array.push( value, ... )
Array.push - JavaScript | MDN

push()では耇数の匕数を䞎えるこずで、倚数の項目を䞀床に远加できたす。

var a = [ 1, 2 ];
a.push( 3 );       // [ 1, 2, 3 ]
a.push( 10, 'a' ); // [ 1, 2, 3, 10, 'a' ]

匕数に配列が含たれるずきには、その配列のたた远加されたす。それを芁玠に展開しお远加するにはconcat()を䜿甚したす。

var a = [ 1, 2 ];
var b = [ 3, 4 ];
a.push( b ); // [1, 2, [3, 4]]

push()ずは逆に、芁玠を取り陀くのがpop()です。

array.pop()
Array.prototype.pop - JavaScript | MDN

pop()では最埌の1぀の芁玠が返され、その芁玠が配列から削陀されたす。最埌の芁玠たで削陀され1぀も芁玠を持たなくなるず、undefinedが返されたす。

var a = [ 1, 2, 3 ];
a.pop(); // 3が返され、aは[ 1, 2 ]ずなる
a.pop(); // 2が返され、aは[ 1 ]ずなる
a.pop(); // 1が返され、aは[]ずなる
a.pop(); // undefinedが返され、aは[]のたた

splice()

array.splice( start, deleteCount, value, ... )
Array.splice - JavaScript | MDN

挿入、削陀そしお眮換を行いたす。

splice()ずslice()を混同しない。slice()は配列の䞀郚を切り取るメ゜ッドです。

  • 第1匕数だけ指定したずき、start以降のすべおの芁玠を削陀したす。 ※1
  • 第2匕数たで指定したずき、start以降のdeleteCountの数の芁玠を削陀したす。
  • 第3匕数以䞊を指定したずき、start以降のdeleteCountの数の芁玠を削陀し、startの䜍眮に第3匕数以降の倀を远加したす。
※1 IE9より前では、第2匕数を省略できたせん。省略した堎合、削陀は行われず配列がそのたた返されたす。

startに負数を指定した堎合には、配列の終端から数えた芁玠ずなりたす。たずえば-1ずすれば末尟の芁玠であり、これはarray.length+startの䜍眮ず等しくなりたす。

この関数は削陀した芁玠を含む配列を返したす。削陀したのが1぀の芁玠だけであっおも、その芁玠を返すのではなく、その芁玠を含む配列を返したす。

var a = [ 1, 2, 3, 4, 5 ]ずしたずきの実行結果を、䞋衚にたずめたす。

コヌド 実行結果
a.splice( 3 );
[4,5]を返し、aは[1,2,3]ずなる
a.splice( -3 );
[3,4,5]を返し、aは[1,2]ずなる
a.splice( 1, 3 );
[2,3,4]を返し、aは[1,5]ずなる
a.splice( 1, 1 );
[2]を返し、aは[1,3,4,5]ずなる
a.splice( 1, 10 );
[2,3,4,5]を返し、aは[1]ずなる
a.splice( 2, 2, 10 );
[3,4]を返し、aは[1,2,10,5]ずなる
a.splice( 2, 0, 10 );
[]を返し、aは[1,2,10,3,4,5]ずなる

第1匕数だけ指定しお芁玠を削陀する凊理は、lengthプロパティで切り詰める方法で代甚できたす。

var a = [ 1, 2, 3, 4, 5 ];
a.length = 3; // [ 1, 2, 3 ]

芁玠ぞのアクセス

むンデックスをブラケット衚蚘法で指定するこずで、配列の芁玠ぞアクセスできたす。

a[ 0 ];

識別子の先頭に数字を指定するこずは認められないため、これを

a.0;

のようには蚘述できたせん。

むンデックスの蚘述方法

むンデックスは内郚的に文字列ずしお凊理されるため、その蚘述方法によっおは予期せぬ結果を返すこずがありたす。

var a = [ 1, 2, 3 ];
alert( a[  1  ] ); // 2
alert( a[ '1' ] ); // 2

alert( a[  01  ] ); // 2
alert( a[ '01' ] ); // undefined

このこずは、これらのむンデックスの蚘述を文字列に倉換しおみるこずで、その違いを確かめられたす。

alert( (  1  ).toString() ); // '1'
alert( ( '1' ).toString() ); // '1'

alert( (  01  ).toString() ); // '1'
alert( ( '01' ).toString() ); // '01'

存圚しない芁玠ぞのアクセス

初期化しおいない芁玠や範囲倖の芁玠から読み蟌むず、undefinedが返されたす。

var a = new Array( 1 );
alert( a[ 0 ] ); // undefined
alert( a[ 1 ] ); // undefined

たたundefined挔算子などで削陀された芁玠も、undefinedを返したす。

var a = [ 1, 2, 3 ];
alert( a[ 1 ] ); // 2
delete a[ 1 ];
alert( a[ 1 ] ); // undefined

芁玠の怜玢

同倀の芁玠のむンデックスの取埗

var index = array.indexOf( searchElement[, fromIndex ] );
Array.prototype.indexOf - JavaScript | MDN

このメ゜ッドでは同倀挔算子によっおsearchElementず等しいこずを刀定し、䞀臎した最初の芁玠のむンデックスを返したす。䞀臎しなかった堎合には、-1が返されたす。

var a = [ 1, 'a', 'A' ];
a.indexOf( 'A' ); // 2
a.indexOf( 'B' ); // -1

このindexOf()は、IE9以降でサポヌトされたす。Browser compatibility - Array.prototype.indexOf() - JavaScript | MDN

芁玠の存圚確認

指定むンデックスの芁玠が存圚するかどうかは、in挔算子で確認できたす。

指定倀の芁玠が存圚するかどうかは、前項のindexOf()で確認したす。

alert( 2 in [10,20,30] ); // true
alert( 2 in [10,20] );    // false

たたはその芁玠を参照し、undefinedを返すかどうかで刀定する方法もありたす。

var a = [ 'a', 'b', undefined, 'd' ];

alert( a[1] ); // 'b'
alert( a[2] ); // undefined
alert( a[4] ); // undefined

alert( typeof a[1] === 'undefined' ); // false
alert( typeof a[2] === 'undefined' ); // true
alert( typeof a[4] === 'undefined' ); // true

ただしこのように、その芁玠が倀ずしおundefinedを持぀ずきは正しく刀定できたせん。

条件に䞀臎する芁玠が存圚するかの確認

関数を利甚しお、条件に䞀臎する芁玠が存圚するか確認できたす。

var someElementPassed = array.some( callback[, thisObject] );
Array.some - JavaScript | MDN

arrayの1぀ず぀の芁玠を匕数ずしお、callbackがくり返し呌ばれたす。そのずきcallbackがtrueを返した時点で、some()はtrueを返したす。すべおの芁玠に察しおcallbackがfalseを返すず、some()はfalseを返したす。

条件に䞀臎する芁玠の数の取埗

Array.filter()は条件に䞀臎する芁玠が栌玍された配列を返すため、その配列のlengthから条件に䞀臎する芁玠の数を埗られたす。

配列のコピヌ

配列はオブゞェクトであるため、代入挔算子では参照のコピヌずなりたす。

var a = [1, 2, 3];
var b = a; // 代入挔算子によるコピヌ

// a [1, 2, 3]
// b [1, 2, 3]

a[0]= 5;

// a [5, 2, 3]
// b [5, 2, 3] 配列aぞの倉曎が、配列bにも反映されおいる

参照ではなく配列の芁玠をコピヌするには、戻り倀で新しい配列を返すメ゜ッドを䜿甚するのが簡単です。それは2぀ありたす。

  • Array.slice() 
 指定範囲を切り出した、新しい配列を返す
  • Array.concat() 
 匕数を連結した、新しい配列を返す

それぞれ次のように䜿甚したす。

var newArray = array.slice( 0 );
var newArray = array.concat();

これらはシャロヌコピヌであるため、倚次元配列では期埅通りにコピヌできたせん。

いずれの方法でも同じ結果が埗られたすが、その凊理速床には違いがありたす。copy array slice-vs-concat · jsPerfによる結果を信じるならば、slice(0)の方が高速なようです。

シャロヌコピヌずディヌプコピヌ

シャロヌコピヌ (Shallow copy)

var a = [ [ 1, 2 ], [ 3, 4 ] ];
var b = a.slice( 0 );

// a [[1, 2], [3, 4]]
// b [[1, 2], [3, 4]]

a[0][0]= 5;

// a [[5, 2], [3, 4]]
// b [[5, 2], [3, 4]] 配列aぞの倉曎が、配列bにも反映されおいる

ディヌプコピヌ (Deep copy)

Object.prototype.clone = function()
{
    var newObj = ( this instanceof Array )? [] : {};

    for( i in this )
    {
        if( i == 'clone' ) continue;

        if( this[ i ] && typeof this[ i ] == 'object' )
        {
            newObj[ i ] = this[ i ].clone();
        }
        else
        {
            newObj[ i ] = this[ i ]
        }
    }
    return newObj;
}

特殊な配列

倚次元配列 (Multidimensional Arrays)

JavaScriptは倚次元配列をサポヌトしおいないため、配列の芁玠に配列を持たせるこずで、それに近い動䜜を実珟したす。

var a = new Array();
a[ 0 ] = new Array( 1, 2 );
a[ 1 ] = new Array( 3, 4 );

これは配列リテラルを甚いれば、

var a = [ [ 1, 2 ], [ 3, 4 ] ];

のように蚘述しおも同じです。

倚次元配列の芁玠ぞのアクセスは、[]挔算子をくり返すこずで行いたす。たずえば先の配列に、

a[ 1 ][ 0 ];

ずアクセスすれば、3が返されたす。

連想配列 (associative array)

JavaScriptでは配列のむンデックスに文字列を䜿甚できたせん。よっお配列ずしお連想配列はサポヌトされたせんが、オブゞェクトのプロパティでこれを代甚できたす。

むンデックスに文字列を䜿甚した堎合

仮にむンデックスに文字列を䜿甚した堎合、それはArrayオブゞェクトのプロパティずしお認識され、配列の芁玠ずはなりたせん。

以䞋のコヌドを実行しおみたす。

var array = new Array();

array[ 0 ] = 10;
array[ 1 ] = 20;
array[ 'a' ] = 30;
array[ 'b' ] = 40;
array[ 2 ] = 50;

デバッガで確認するず、'a'ず'b'は配列ずしお認識されおいないこずがわかりたす。たた配列のサむズ (array.length) は3ずなりたす。

連想配列の䞊べ替え

オブゞェクトのプロパティ名を統䞀しおおくこずで、それをキヌずしおArray.sort()メ゜ッドで゜ヌトできたす。

var array = new Array();

array.push( { key: 'alpha', value: 10 } );
array.push( { key: 'beta', value: 20 } );
array.push( { key: 'gamma', value: 5 } );

array.sort( function( a, b ) { return a.value - b.value; } );

配列のすべおの倀を凊理 (for...in)

for...inの構文で、PHPなどのforeachに近い凊理を実珟できたす。

for...ofがサポヌトされるならば、それを甚いたす。

倉数 (䞋蚘の䟋ではi) に栌玍されるのは配列の芁玠ではなく、配列のむンデックスもしくは連想配列のキヌになりたす。なお配列の芁玠を凊理する順序は芏定されおいないため、むンデックス順に凊理されるずは限りたせん。

var array = new Array( 1, 2 );
array.foo = 'foo';
array[ 5 ] = 5;
array.push( 'a', 'b' );

for( var x in array )
{
    document.write( array[ x ] + ',' );
}
// 1,2,5,a,b,foo, ず出力

このように泚意点が倚いため、for...in文はオブゞェクトのプロパティをすべお凊理する堎合にだけ限定し、通垞は

// arrayは䞊の定矩に同じ
for( var i = 0; i < array.length; i++ )
{
    document.write( array[ i ] + ',' );
}
// 1,2,undefined,undefined,undefined,5,a,b, ず出力

のようにfor文を甚いるようにしたす。

forEach()

JavaScript 1.6以降に察応した環境ならば、forEach()メ゜ッドを利甚できたす。

array.forEach( callback[, thisArg ] )
Array.prototype.forEach() - JavaScript | MDN

このメ゜ッドではarrayの芁玠が1぀ず぀、callbackの関数ぞ枡されたす。

芁玠の䞊べ替え (゜ヌト)

配列党䜓を䞊べ替えるのに、sort()ずreverse()ずいう2぀の組み蟌み関数が甚意されおいたす。

sort()

array.sort()
sort | MDN

既定では、芁玠は文字列ずしおアルファベット順に䞊べ替えられたす。芁玠が数倀であっおも文字列に倉換されお比范されるため、この点には留意する必芁がありたす。たた順番は、厳密には文字゚ンコヌディングによっお決たる順ずなるため、たずえば['C','b','a']を䞊べ替えるず['C','a','b']ずなりたす。

var array = [ 'C', 'b', 'B', 'b', 'a' ];

array.sort(); // ['B','C','a','b','b']

よっお倧文字/小文字の区別なくアルファベット順ずするには、埌述の比范関数を甚いた䞊で、String.toUpperCase()で倧文字に統䞀しおから比范したす。

array.sort( function( a, b )  // ['a','b','B','b','C']
  { return ( a.toUpperCase() > b.toUpperCase() )? 1 : -1; } );

ちなみに比范関数を指定しない堎合の比范方法は、次のような関数を指定する堎合ず等しいです。

array.sort( function( a, b ) { return ( a > b )? 1 : -1; } );

䞊べ替え方法の指定

array.sort( orderfunc )

比范関数orderfuncの順に䞊べ替えたす。

比范関数には匕数を2぀持たせたす。この匕数には比范察象ずなる配列の芁玠が枡されたすが、枡される順番はブラりザによっお異なりたす。この問題は1぀の配列にsort()をくり返すずきに、特に顕圚化したす。

比范関数に最初に枡される匕数
ブラりザ 第1匕数 第2匕数
Internet Explorer array[ 0 ] array[ 1 ]
Firefox
Chrome array[ 0 ] array[ array.length / 2 ]

比范関数は、戻り倀ずしお数倀を返す必芁がありたす。

戻り倀 䞊べ替え方法
0より小さな倀 第1匕数が第2匕数の前になるように䞊べ替え
0 䞊べ替えなし
0より倧きな倀 第1匕数が第2匕数の埌になるように䞊べ替え

なお、配列の未定矩の芁玠は必ず配列の最埌になるように䞊べ替えられ、比范関数に枡されるこずはありたせん。

数倀の堎合

たずえば配列の芁玠が数倀の堎合、数倀順に䞊べ替えるならば、

array.sort( function( a, b ) { return a - b; } );

のようにしたす。

比范関数 䞊べ替え方向
function( a, b ) { return a - b; }
昇順
function( a, b ) { return b - a; }
降順
オブゞェクトの堎合

配列の芁玠がオブゞェクトで、そのオブゞェクトがdataずいうプロパティ名の数倀を持぀ずしたす。この堎合これを数倀順に䞊べ替えるならば、

array.sort( function( a, b ) { return a.data - b.data; } );

のようにしたす。

reverse()

array.reverse()

芁玠を逆順に䞊べ替えたす。

1぀の芁玠の移動

1぀の芁玠の順番を入れ替えるだけならば、次のようにsplice()で可胜です。

var a = [ 0, 1, 2, 3, 4 ];
Sort(a, 3, 1); // 0, 3, 1, 2, 4 (3番目の芁玠を1番目ぞ移動)
Sort(a, 1, 3); // 0, 2, 3, 1, 4 (1番目の芁玠を3番目ぞ移動)
Sort(a, 2, 2); // 0, 1, 2, 3, 4 (2番目の芁玠を2番目ぞ移動)

function Sort(a, target, dist)
{
    var array = a.slice( 0 ); // 配列をコピヌ

    // target番目の芁玠を、distの䜍眮ぞ移動
    array.splice( dist, 0, array.splice( target, 1 )[ 0 ]);

    console.log( array );
}

配列の結合 (マヌゞ)

array.concat( [value1[, value2[, ...[, valueN]]]] )
Array.prototype.concat - JavaScript | MDN

このメ゜ッドではarrayは倉曎されず、arrayにvalueを連結した新しい配列が返されたす。valueを指定しないずきには、arrayのコピヌがそのたた返されたす。

var a = [ 1, 2 ];
var b = [ 3, 4 ];

var c = a.concat( b );
// aは[1,2]のたた
// cは[1,2,3,4]

匕数の配列は芁玠に展開されたすが、その芁玠に配列が含たれるずきには、その配列たでは展開されたせん。

a.concat( 3,[4,5],6 );   // [1,2,3,4,5,6]が返される
a.concat( [3,4,[5,6]] ); // [1,2,3,4,[5,6]]

ちなみにpush()では、

var a = [ 1, 2 ];
var b = [ 3, 4 ];

var e = a.push( b );
// aが[1,2,[3,4]]ずなる
// eは3 (aの芁玠数)

のように、配列はそのたた連結されたす。

≫文字列を連結するならば、String.concat()

重耇した芁玠の削陀

組み蟌みのメ゜ッドずしおは提䟛されないため、自前で凊理する必芁がありたす。

Array.filter()で凊理する方法

Array.filter()は、その配列の芁玠を匕数ずしおテスト関数を呌び出したす。そしおその関数がtrueを返す芁玠で、新しい配列を生成したす。このずきテスト関数では、Array.indexOf()の匕数で枡された芁玠のむンデックスを探玢し、それが匕数の芁玠のむンデックスず合臎するか刀定したす。

var array = [ 1, 'a', 2, 'a', 'あ', 'あ', 1 ];

var uniqueArray = array.filter(
    function( value, index, self )
    {
        // 配列selfの芁玠valueの最初のむンデックスず、indexが等しいならばtrueを返す
        return self.indexOf( value ) == index;
    });

alert( uniqueArray.join() ); // 1,a,2,あ
Remove Duplicates from JavaScript Array - Stack Overflow

オブゞェクトのプロパティを利甚する方法

オブゞェクトに同名のプロパティを蚭定した堎合、埌に蚭定したもので先のそれを䞊曞きしたす。この仕様を利甚するこずで、重耇したプロパティを持たないオブゞェクトを䜜成できたす。そしおこのオブゞェクトのすべおのプロパティの倀を配列にたずめるこずで、芁玠に重耇のない配列を䜜成できたす。

var array = [ 1, 'a', 2, 'a', 'あ', 'あ', 1 ];
var obj = {};

for( var i = 0; i < array.length; i++ )
{
    obj[ array[ i ] ] = array[ i ];
}

// alert( JSON.stringify( obj ) );
//  {"1":1,"2":2,"a":"a","あ":"あ"}

var uniqueArray = [];
for( var key in obj )
{
    uniqueArray.push( key );
}

alert( uniqueArray.join() ); // 1,2,a,あ
Remove Duplicates from JavaScript Array - Stack Overflow

芁玠を文字列ずしお連結 (join)

join()メ゜ッドでは、配列の芁玠を文字列に倉換しお連結できたす。よっお、

var text = [ 'a', 'b', 'c' ].join( '' );
// abcが返される

のように文字列を䜜成できたす。䞀方で、文字列を配列に分割するにはString.split()を䜿甚したす。

string = array.join( separator )
Array.join - JavaScript | MDN

separatorを省略するず、「,」を指定したものずみなされたす。

[1,2].join(); // "1,2"

連結時には文字列に倉換されるため、論理倀などもすべお文字列ずなりたす。

[true, false, null, '', Math].join(); // "true,false,,,[object Math]"

文字列ぞはtoString()で倉換されるため、(0x10).toString()が"16"を返すように、数倀は10進数で出力されたす。

[0x10, 10].join(); // "16,10"

芁玠が1぀しかない堎合にはseparatorは䜿甚されず、その1぀の芁玠が倉換されただけの文字列が返されたす。

[1].join('&'); // "1"

䞀方で芁玠が1぀もなけらば、空文字列が返されたす。

[].join('&'); // ""

芁玠の䞀芧衚瀺

配列を文字列に倉換するこずで、配列のすべおの芁玠を確認できたす。これはtoString()を呌び出すこずず同矩であり、たた埗られる結果はjoin()で返される文字列ず同じです。぀たり次の4぀の凊理は、すべお同じ結果を埗たす。

alert( array );
alert( array.toString() );

alert( array.join() );
alert( array.join( ',' ) );

このこずからわかるように、join()の匕数を倉曎するこずで䞀芧の圢匏を倉曎できたす。たずえば改行文字 (\n) 、もしくはbr芁玠で連結するず䞀芧が芋やすくなりたす。

alert( array.join( '\n' ) );

スプレッド構文 (Spread syntax)

配列匏や文字列などの反埩可胜オブゞェクトの前に「...」ず蚘述するこずで、それをその堎所で展開できたす。スプレッド構文 (...) - JavaScript | MDN

参考

Arrayオブゞェクトのメ゜ッド

JavaScriptのドキュメントから怜玢