【りあクト!1】コレクションの反復処理
タグ:
JavaScript
ふわっと分かるなんと無く使えるけど、実はよく理解していないものの代表。
リテラル(Literal)
「literal」は「文字通り」の意味。 通常はプリミティブ型の値を定義するモノのことを指す。
- ・Boolean型を返す真偽直リテラル
- ・Number型を返す数値リテラル、浮動小数点リテラル
- ・String型を返す文字列リテラル など。
これ以外にオブジェクト型の値を定義するリテラルがある。
- ・Arrayオブジェクトのインスタンスとして生成される配列リテラル。 [1,2,3]の形式で表記する。いわゆるリストやArrayList
- ・Objextオブジェクトのインスタンスとして生成されるオブジェクトリテラル。{ key: value } の形式で表記する。いわゆる連想配列やMap
- ・RegExpオブジェクトのインスタンスとして生成される正規表現リテラル。/pattern/frags の形式で表記する。
配列リテラルの反復処理
Arrayオブジェクトのprototypeメソッドを利用するのが良い。 ・引数を1つ取るもの
- ・map() 対象の配列の要素ひとつひとつを任意に加工した新しい配列を返す。
- ・filter() 与えた条件に適合する要素だけを抽出した新しい配列を返す。
- ・find() 与えた条件に適合した最初の要素を返す。(ES2015)
- ・findIndex() 与えた条件に適合した最初の要素のインデックスを返す。(ES2015)
- ・every() 与えた条件をすべての要素が満たすかを真偽値で返す。
- ・some() 与えた条件を満たす要素がひとつでもあるかを真偽値で返す。
- ・includes() 指定した値の要素がひとつでも含まれているかを真偽値で返す。(ES2016)
const arr = [1,2,3,4,5,6,7,8,9]; console.log(arr.map((n)=>n*2)); //[2,4,6,8,10,12,14,16,18] console.log(arr.filter((n)=>n%3 === 3)); //[3,6,9] console.log(arr.find((n)=>n>4)); //5 console.log(arr.findIndex((n)=>n>4)); //4 console.log(arr.every((n)=> n!==0)); //true console.log(arr.some((n)=> n>= 10)); //false
・引数を2つ取るもの
- ・reduce(n,m) nに前回の関数の実行結果、mに対象の配列の要素を順に代入し、結果を返す
- ・sort(n,m) nとmを比較関数によって比較し、並び替えを行う。
const arr = [1,2,3,4,5]; console.log(arr.reduce((n,m) => n + m)); // 15 console.log(arr.sort(n,m) => n > m ? -1 : 1)); // [5,4,3,2,1]
そのほかに配列の反復処理で値を返さない構文がある。
- ・Array.prototype.forEach() mapなどに似た書き方。
- ・for...of Javaの拡張for文に近い書き方。
arr.forEach((n) => { if (n % 2 === 0){ console.log(`${n} is even`); } }); for (let n of arr){ if ( n % 2 !== 0){ console.log(`${n} is odd`); } }
ただし、これら2つの値を返さないメソッドはその内部で外部と変数を書き換えること(これを 副作用 と呼ぶ)が目的になることが多い。 AirbnbのJavaSriptスタイルガイドには、バグの原因になる可能性を含むので極力使わないようが良いとに書かれている。
オブジェクトリテラルの反復処理
- ・Object.keys(A) Aのkeyを配列で返す。
- ・Object.values(A) Aのvalueを配列で返す。
- ・Object.entries(A) Aのkeyとvalueが対になった2次元配列を返す。
注意するのはインスタンス自身にkeysやvaluesといったメソッドがあるのではなく、Object自身がこれらのメソッドを持っているということ。 keysやvaluesで作成した配列に対して,配列のメソッドを用いて反復処理を適用すると良い。
追記:HTMLCollectionの反復処理
getElementByTagName()などで取得できるHTMLCollectionはリストの形に見えるがそのままでは反復処理ができないので、 Array.form()を使って変形してあげる必要がある。
const elems = document.getElementsByTagName('div'); // HTMLCollectionはそのままではループできない const elemsArray = Array.from(elems); console.log(elems); console.log(elemsArray); elemsArray.map((elem) => ( // 行いたい処理 );