情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

ECMAScript 6の新機能(17)配列関連関数

ECMAScript 6で新しい配列関連関数が幾つか追加されました。

Array.from

これは配列に似ているオブジェクトやイテラブルを配列に変換する関数です。

配列に似ているオブジェクトとはインデックスをキーとするプロパティとlengthプロパティの両方を有するオブジェクトです。

下は配列に似ているオブジェクトを配列に変換する例です。

配列に似ているオブジェクトに対してfor-of文でループすることはできませんが、配列はイテラブルであるため配列に変換すればループすることができます。

C:\work\node>node
> var arrayLike = { length: 2, 0: 'foo', 1: 'bar' }
undefined
> for (var x of arrayLike) {
... console.log(x);
... }
TypeError: arrayLike[Symbol.iterator] is not a function
    at repl:1:15
    at REPLServer.defaultEval (repl.js:272:27)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:441:10)
    at emitOne (events.js:101:20)
    at REPLServer.emit (events.js:188:7)
    at REPLServer.Interface._onLine (readline.js:219:10)
    at REPLServer.Interface._line (readline.js:561:8)
    at REPLServer.Interface._ttyWrite (readline.js:838:14)
> for (var x of Array.from(arrayLike)) {
... console.log(x);
... }
foo
bar
undefined

なお、配列に似ているオブジェクトに穴(値が設定されていない要素)がある場合には穴の値はundefinedであるものとして扱われます。

C:\work\node>node
> var arrayLike = { length: 3, 0: 'foo', 2: 'bar' }
undefined
> for (var x of Array.from(arrayLike)) {
... console.log(x);
... }
foo
undefined
bar
undefined

下はイテラブルの1つである文字列を配列に変換する例です。

C:\work\node>node
> var str = 'this is a string'
undefined
> str
'this is a string'
> var array = Array.from(str)
undefined
> array
[ 't',
  'h',
  'i',
  's',
  ' ',
  'i',
  's',
  ' ',
  'a',
  ' ',
  's',
  't',
  'r',
  'i',
  'n',
  'g' ]

Array.of

これは0個以上の値から配列を作成する関数です。

> Array.of()
[]
> Array.of('foo')
[ 'foo' ]
> Array.of('foo', 'bar')
[ 'foo', 'bar' ]
> Array.of('foo', 'bar', 'baz')
[ 'foo', 'bar', 'baz' ]

イテラブル

ECMAScript 6で配列をイテラブルに変換する関数が3つ追加されました。

Array.entries

これは配列の全ての要素のインデックスと値の配列から成るイテラブルを返す関数です。

C:\work\node>node
> for (var [k, v] of ['foo', 'bar', 'baz'].entries()) {
... console.log(k + ' ' + v);
... }
0 foo
1 bar
2 baz
undefined

上のコードではfor-of文のvar [k, v]という部分でECMASCripr 6で追加された配列の分解を使用しています。

Array.keys

これは配列の全ての要素のインデックスから成るイテラブルを返す関数です。

C:\work\node>node
> for (var k of ['foo', 'bar', 'baz'].keys()) {
... console.log(k);
... }
0
1
2
undefined

Array.values

これは配列の全ての要素の値から成るイテラブルを返す関数です。

要素の検索

ECMAScript 6で配列の要素を検索する関数が2つ追加されました。

Array.find

これは配列の要素の中で条件を満たす最初のものの値を返す関数です。

条件は関数として指定します。この関数の第1引数は要素の値であり、第2引数は要素のインデックスであり、第3引数は配列です。要素が条件を満たす場合にはtrueを返し、満たさない場合にはfalseを返すようにします。

この条件を表す関数を配列の最初の要素から順番に適用していくことにより条件を満たす要素を検索します。条件を満たす要素が見付かった場合には即座にその要素が返り、1つも見付からなかった場合にはundefinedが返ります。

C:\work\node>node
> [101, 200, 444].find(function (x) { return x % 2 === 0; })
200
> [100, 200, 444].find(function (x) { return x % 2 === 1; })
undefined

なお、配列の穴の値はundefinedであるものとして扱われます。

> [, , ].find(function (x) { return x !== undefined; })
undefined

Array.findIndex

これは要素のインデックスを返すという点以外はArray.find関数と同じです。

ただし、条件を満たす要素が1つも見付からなかった場合には-1が返ります。

> [101, 200, 444].findIndex(function (x) { return x % 2 === 0; })
1
> [100, 200, 444].findIndex(function (x) { return x % 2 === 1; })
-1
> [, , ].findIndex(function (x) { return x !== undefined; })
-1

Array.copyWithin

これは配列の一部分の要素の値を別の一部分にコピーする関数です。

第1引数にコピー元の最初の要素のインデックスを指定します。

第2引数にコピー先の最初の要素のインデックスを指定します。

第3引数にコピー先の最後の要素のインデックスに1を加えたものを指定します。

C:\work\node>node
> var array = [0, 1, 2, 3, 4, 5]
undefined
> array.copyWithin(2, 1, 4)
[ 0, 1, 1, 2, 3, 5 ]

Array.fill

これは配列の一部分の要素の値を一定の値に設定する関数です。

第1引数に値を指定します。

第2引数に値を設定する部分の最初の要素のインデックスを指定します。

第3引数に値を設定する部分の最後の要素のインデックスに1を加えたものを指定します。

C:\work\node>node
> var array = [0, 1, 2, 3, 4, 5]
undefined
> array.fill(777, 1, 4)
[ 0, 777, 777, 777, 4, 5 ]

Array.concat

これはECMAScript 5にもある関数であり、配列に要素を追加する関数です。

デフォルトではこの関数は引数に配列が指定された場合にのみその配列を分解して全ての要素を配列に追加し、配列に似たオブジェクトが指定された場合にはそのままそのオブジェクトを配列に追加します。

C:\work\node>node
> [1, 2].concat([3, 4])
[ 1, 2, 3, 4 ]
> [1, 2].concat({ length: 2, 0: 3, 1: 4 })
[ 1, 2, { '0': 3, '1': 4, length: 2 } ]

ECMAScript 6でこの動作を変更することができるようになりました。

配列に似たオブジェクトのSymbol.isConcatSpreadableというシンボルをキーとするプロパティにtrueを設定すると配列に似たオブジェクトも配列と同様に扱われるようになります。

> var arrayLike = { length: 2, 0: 3, 1: 4 }
undefined
> arrayLike[Symbol.isConcatSpreadable] = true
true
> [1, 2].concat(arrayLike)
[ 1, 2, 3, 4 ]

逆に、falseを設定すると配列も配列に似たオブジェクトと同様に扱われるようになります。

> var array = [3, 4]
undefined
> array[Symbol.isConcatSpreadable] = false
false
> [1, 2].concat(array)
[ 1, 2, [ 3, 4 ] ]
pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-ecmascript 2015, ecmascript 6, Javascript