JavaScript 配列の基礎
気づいてしまった、、PHPなどのプログラミング言語に共通して言えることは、、
それは。。
「配列の操作を覚えれば制作物の実装方法が見えてくる」
という妄想が膨らんできたので早速配列の操作方法で覚えたことの復習がてら書き記していこうと思います
文字列配列のメソッド
join(引数に入れた文字で配列の値を区切る)
join()
は配列の値を文字列として連結することができます
以下は例文です
const baseExcludeTexts = ['o', 'O', '0', 'I', 'l', '1']; document.getElementById("excludeTexts").value = baseExcludeTexts.join(',');
この例では配列として用意しておいた文字列の値に対してHTMLのインプットの値として文字列へ変換して格納していますjoinしたものをconsole.logでみてみます
o,O,0,I,l,1
となっており配列ではなく文字列となっています
そして改行する場合などは<br>タグや「/n」で改行することができます
split — 引数の文字で区切って配列へ変換する
今度はjoinの逆で文字列を配列として変換するメソッドです。。
使用方法などはjoinの逆で先の続きの例です
const excludeTexts = inputs.excludeTexts.value.split(","),
ここの例ではHTMLにて入力されたインプットの値に対してカンマ区切りで配列に変換して変数にしています
このメソッドの面白いところは文字列の置換を行うことが出来るという点です
文字列に対して配列に変換する際に引数に指定した文字で区切ることができるので、
その配列に対してjoin
で区切りたい文字を入れて、文字列化することで文字の置換ができます
具体的には。。
const date = '2021/10/10', result = date.split('/').join('-'); console.log(result);
上記のコードの例では、実行結果は
「2021-10-10」という実行結果になり、先に用意した文字列の一部を置換する結果になっています
一度配列の一部として「/」で切り分けたあとにすぐ「ー」で文字列に変換してやることで事実上の置換の役割を果たしてくれます
これら二種類、join
とsplit
はセットでよく使うメソッドですね
配列に要素を追加する
push(引数にした要素を配列に追加する)
配列の末尾に要素を追加する際に使用するメソッドです
使用例から見てみましょう
// 試験の点数(国語、算数、理科) const score_kokugo = 80; const score_sansu = 90; const score_rika = 70; // データ無しで配列を定義 let scores = []; // 点数を追加 scores.push(score_kokugo); scores.push(score_sansu); scores.push(score_rika); // 結果を確認 console.log(scores); // => [80, 90, 70]
このメソッドの特徴としては追加した要素は配列の最後尾に追加される点とオブジェクトを追加することも出来るという点です
unshift (先頭に要素を追加)
unshift
メソッドは配列の先頭に要素を追加します
配列.unshift(追加したい要素,[追加したい要素2, ...]);
配列から要素を削除
shift —先頭を削除
shift
メソッドは配列から先頭の要素を削除します
let 削除した要素 = 配列.shift();
pop —末尾を削除
popメソッドは配列から末尾の要素を削除します
let 削除した要素 = 配列.pop();
splice —要素の切り取り
let 切り取られた配列 = もとの配列.splice(開始位置, 長さ[, 追加要素1,ついか2,...]);
splice
は特定の要素を切り取ります。この時元になる配列から要素が削除されることに注意しましょう
元の配列を維持したまま特定の要素を切り出したい時は下記slice
を使用します
またsplice
では第三引数以下の要素を、要素を削除した箇所に追加することが出来ます
const fruitsB = ["banana", "orange", "grape"]; fruitsB.splice(1, 1, "apple", "lemon"); // "orange" を削除し、"apple"、"lemon"を追加 console.log(fruitsB); // > ["banana", "apple", "lemon", "grape"]
配列の結合・複製
配列の結合や複製(コピー)を行う場合はconcat
メソッドを使用します
また特定の要素を複製したい場合にはslice
メソッドを使います
slice —特定の要素を抽出した新しい配列の作成
sliceメソッドは開始位置から終了位置の直前の要素までを抽出した新しい配列を返します
let 切り取られた配列 = 元の配列.slice([開始位置, 終了位置]);
配列に対して引数で指定した範囲を切り取った新しい配列を返すメソッドです
つまり元の配列には影響しません
const fruits = ["banana", "orange", "grape"]; const newFruits = fruits.slice(1, 2); console.log(newFruits); // > ["orange"] 終了位置の要素(grape)は含んでいないことに注意 console.log(fruits); // > ["banana", "orange", "grape"] 元の配列に影響はない // 終了位置を指定しない場合、開始位置からのすべての要素が複製される const toEndFruits = fruits.slice(1); console.log(toEndFruits); // > ["orange", "grape"] // 開始位置、終了位置を指定しない場合、すべての要素が複製される const allFruits = fruits.slice(); console.log(allFruits); // > ["banana", "orange", "grape"]
引数は切り抜き開始位置と終了位置で終了位置の値は含まないという注意点もあります
面白いのは引数を指定せずに使用するとディープコピーを生成する事ができます
具体的には破壊的なメソッドを使用する前に元の配列をコピーしておいたりすることが簡単に出来るという事です
concat —配列の結合と複製
concatメソッドで別の配列を結合することが出来ます
let 結合された配列 = 配列1.concat(配列2);
またconcat
もslice
も引数を省略して代入演算子を利用して、配列の複製を行うことが出来ます
近年のモダンな開発で配列の結合や複製を行う場合には、スプレッド演算子を使うのが主流なようで、これをしっかり覚えておくことでこのメソッドは必要なさそうに感じました
イテレートなメソッド(ループするやつ)
代表的なforEach
などメソッドの中でコールバック関数を引数にして配列をループ処理するものをまとめてみます
関連の深いメソッドなども紹介するため用途は違えどすべて実用的です
ここで紹介するメソッドの引数はreduce以外はすべて同じで
配列.メソッド(配列の値, index, 元の配列){ 何かしらの処理 };
と上記のようになっています、どの引数も状況によって上手く使える方法が多いようです
map —新しい配列を返す
このmap()
メソッドですが、元となる配列から新しい配列を作成するメソッドとなっています。
これらの配列操作系の基本であり配列の値に何かしらの操作をして新しい配列の変数を生成するように用います
const items = [1, 2, 3, 4, 5] const doubleItems = items.map( function (item) { return item * 2 })
上記の例だと配列の値がすべて二倍になった値の配列を作っています
これはシンプルな配列を作成するのに使うことが多いようで例えば多重連想配列でのデータの中から「name」の値だけを取り出した配列を新たに作成したい場合などアロー関数も使用して書けばスッキリ書くことができます
const names = animals.map(item => item.name)
こんな感じですね
forEach
とよく似ていますがmapは戻り地として新しい配列を返す点が異なります
filter —値を条件付きで順に処理する
filter()はその言葉どおり配列の値をフィルタリングすることが出来るメソッドで、こちらも使い方が多そうで個人的に面白いメソッドだと思います
実例で見てみましょう
社員一覧のオブジェクトから年齢を絞り込んだ配列を作成します
sampleObject.js
const members = [ { position: '一般社員', name:'渡辺', age: '23' }, { position: '社長', name:'佐藤', age: '45' }, { position: '課長', name:'高橋', age: '35' }, { position: '係長', name:'田中', age: '36' }, { position: '一般社員', name:'伊藤', age: '22' }, { position: '部長', name:'鈴木', age: '48' }, ]
この配列データをfilter
にかけます
const filteredData = members.filter(member => { // 38歳以上 return member.age >= 38 })
メンバーズと名付けた配列に対して年齢:の中に38歳以上のデータのみを抽出されたものが変数filteredData
に代入されます
そしてフィルタリングする際は必ずreturn
する必要があります
配列のデータがすべて順番に処理されて条件にあった新しい配列を生成するということです
find — 条件を満たした最初の要素を取得
filter
と似たメソッドで、find()
と言うものがあります。こちらのメソッドは、一致した最初のものを取得すると言う違いがあります。
条件検索関連で覚えておきたいメソッドがあります
いろいろな処理を巡って配列を受け取った場合など、配列の中身を調べてチェックしたくなる場面が度々あります
indexOf — 最初に一致した添字を返す
let 一致した添字 = 配列.indexOf( 存在確認したい値 );
こちらもfilterメソッドとセットで使われることが多いです
後に用例など載せてみましょうか、、
includes(検索する文字列)
この関数はfilterメソッドとセットで使用することが多くなりそうです
内容としては文字列が含まれているかどうかを真偽値で返してくれるものです
用例です
const filteredData = members.filter(member => { // 名前に「藤」が入っている人 return member.name.includes('藤') })
これで配列の中から名前に「藤」が入っている人のみを抽出することができました
同じように配列のデータを回して処理するもので検索を行い真偽値を返してくれるものもあります
some —少なくとも1つの値が条件に一致するか
先程のfilterのように順に配列を処理し条件に一つでも合致する場合trueを返してくれます
使用例も見てみましょう
console.log(members.some( member => {
return member.position.includes("課長")
}))
この例ではmemberというコールバックを用意して元の配列の中に「課長」が含まれているかどうかの真偽値が返ってきます
結果はtrueですね
条件分岐に使用するのがメインの使用方法になるかと思います 例えば、
let targetName = '藤';
if (members.some((member) => member.name.includes(targetName))) {
afterProcessing.textContent = `メンバーに「${targetName}」の文字は存在します`;
}
ただこれだと少々見づらいので変数化などでスッキリしたほうがいいかもしれませんが
同じように条件検索する処理メソッドですべての条件に合致するメソッドもあるので紹介します
every —すべての値が条件に一致するか
早速使用例で見てみましょう
let targetAge = 22; if (members.every(member => member.age > targetAge)) { afterProcessing.textContent += `メンバーはevery(全員)「${targetAge}歳以上」です`; } else { afterProcessing.textContent += `メンバーに「${targetAge}歳以下」の方がいます`; }
こちらのメソッドevery
も処理の仕方は同じですが、配列の値がすべて合致したときのみtrueを返し、そうでなければfalse
になります
先に紹介したinclude()
メソッドとの違いとしては、
配列に対しては便利なincludes()
メソッドですが、オブジェクト(連想配列)になると単純な比較ではfalse
になってしまいます。
連想配列の場合はsome()
かevery()
で検索するとちゃんとした結果が得られます
sort —配列を並べ替え
sortメソッドは要素の並べ替えを行うことが出来ます
・文字列として昇順で要素を並べ替え
配列.sort();
・比較関数を使って要素を並べ替え
配列.sort( 比較関数 );
昇順にする場合の記述例です
const atrArray = ["b", "c", "a"]; strArray.sort(); console.log( strArray ); > ["a", "b", "c"]
sort
を使って要素を並べ替える場合には、要素の値は文字列として扱われるため、注意しましょう。数値として並べ替える場合には比較関数を定義しコールバック関数として渡します
比較関数
function compare(val1, val2) { if (val1 < val2) { return -1; // 戻り値が0より小さい場合、val1をval2の前に持ってくる } if (val1 > val2) { return 1; // 戻り値が0より大きい場合、val2をval1の前に持ってくる } return 0; // 戻り値が0の場合、val1、val2の並べ替えはしない } const arry = [10, 2, 7, 3, 9]; arry.sort(compare); console.log(arry); // > [2, 3, 7, 9, 10]
数値の並べ替えには比較関数を用意します
比較関数は2つ引数を取り、渡される値は配列の中からランダムに渡された値です
ここで開発者が行うべきことは「渡された2つの値を比べてどちらの値を配列の前の要素に配置したいのかを戻り値でソートアルゴリズムに伝える」ことです。
上記の例のように戻り値として0、負の値、正の値を返すことでソートアルゴリズムに対して2つの値のどちらを前にするか指示できます
オブジェクトはキーでsort()
配列に格納されたオブジェクトに対してのsort
を行う場合も考え方は同じで、
比較関数にはオブジェクトが渡ってくるため、ドット演算子でプロパティを指定して比較します
var fluits = [ {name: 'メロン', price: 500}, {name: 'バナナ', price: 100}, {name: 'りんご', price: 280}, {name: 'イチゴ', price: 300} ]; fluits.sort( (a, b) => { if (a.name > b.name) { return 1; } else { return -1; } })
このようにするとオブジェクトのname
プロパティの値によって並べ替えを行えます
reduce —配列から単一の出力値を生成
最後に紹介するのは一番優秀で可能性を秘めているメソッドreduce()
について紹介します
少し複雑なのでいきなり構文から見てみましょう
const numbers = [10, 20, 50, 60, 100] //配列の値を順番に足していく result = numbers.reduce( (prev, current) => { return prev + current })
この例では配列を左から順番に足し算していき処理が終わる頃にはすべての値の合計が返されます
これを実行しresultをコンソールに出してみると「240」となります
このメソッドは引数が多く複雑なので一つづつ見てみます
const result = array.reduce((前回の値, 現在の値, 現在currentとして処理されている要素のインデックス, reduceによって操作されている配列自身) => {
return 次の値;
}, 初期値);
第一引数は処理された累積結果が
第二引数は処理中の要素
面白いというか設定推奨の初期値という引数があります
第一と第二引数は必須なようです
このメソッドで出来ることは今まで説明してきたすべての内容をこのメソッド一つでできてしまうというすごいメソッドなんですが、、、、
私の頭ではまだい理解しきれていないため参考とするサンプル集をブックマークしておいて実践で使用してみます
その他の便利メソッド
fill — 要素を特定の値で埋める
fill
メソッドは配列の開始位置、終了位置で、範囲指定した添字の要素に対して、特定の値を設定します。 開始位置、終了位置を省略した場合はすべての要素を指定した値で上書きします
配列.fill( 各要素に設定したい値[, 開始位置, 終了位置 ]);
例えば要素数が大きい配列に対して初期値を設定したい場合などに簡単に記述できます
例として長さ100の配列に初期値0を設定したい場合です
const arry = new Array( 100 ); arry.fill( 0 ); > [0, 0, 0, 0, .....] //長さ100,初期値0の配列
flat —多次元配列の平坦化(次元を減らす)
flat
メソッドは多次元配列を引数(平坦化レベル)で指定した次元分、配列の構造を平坦化します。
引数を指定しない場合は1次元分、平坦化します。
let 平坦化された配列 = 多次元配列.flat([ 平坦化レベル ]);
reverse —要素の順番を逆に置換
配列の順番を逆にします
配列.reverse();
Arrayの静的メソッド
JavaScriptの組み込みオブジェクトであるArrayコンストラクタから使用できる静的メソッドの紹介です
form —配列風オブジェクトや反復可能オブジェクトを配列に変換
formメソッドを使うとSetやMap、arguments、HTMLコレクション、NodeListなど、配列ライクなオブジェクトを配列に変換することが出来ます
const set = new Set(); set.add(1); // setオブジェクトに値を追加 set.add(2); set.add(3); const convertedArray = Array.from(set); console.log(convertedArray); // > [1, 2, 3] const map = new Map(); map.set(1, function () { console.log(this); }); console.log(map.get(1)());
isArray — 配列かどうか判定
引数で渡した要素に対して配列かどうか真偽値で返します
const set = new Set(); console.log(Array.isArray(set)); // > false const converedArray = Array.from(set); console.log(Array.isArray(converedArray)); // > true
コメントをお待ちしております