クモのようにコツコツと

フロントエンドエンジニア イイダリョウのブログ。略称「クモコツ」

【JS】多次元連想配列のキー名を外部の変数で指定できるか調べた

ネイティブJSネタです。以前、多次元配列とfor文を絡めて「for文のi番目をホニャララする」という処理を書きました(和音鍵盤でも使ってます)。しかし2箇所を参照する場合に2箇所の順番がズレると成立しなくなりそうです。片方は配列のi番目で指定しつつ、その中の固有値を拾って、もう片方の連想配列のキーを指定したい、といったケースを検証します。それでは行きましょう!

※参考:JS多次元配列に入れたデータをDOMに入力する(JSON未遂事件簿…) - クモのようにコツコツと

※参考:ネイティブJSやってみたシリーズ
qiita.com

【目次】

雛形作成(pタグの中身をinnerHTMLで変更)

まずは雛形を作る。

See the Pen array test 01 by イイダリョウ (@i_ryo) on CodePen.

HTML

<p class="array_text">テスト</p>
  • .array_textのテキストは「テスト」なので本来は「テスト」と表示されるはず(JSで操作している)
const arrayText = document.querySelector('.array_text');

const array = 'aaa';

arrayText.innerHTML = array;
  • 変数arrayTextでDOM.array_textを取得
  • 変数arrayに文字列aaaを入れる
  • arrayTextの中身をinneHTMLarrayに変更

これで. array_textの中身がaaaになる

配列のn番目に変更

さてこれに手を加える。

See the Pen array test 02 by イイダリョウ (@i_ryo) on CodePen.

HTMLは変更なし。JSコードに配列を絡める。

const array = ['aaa','bbb','ccc',];

arrayText.innerHTML = array[1];
  • 変数arrayを配列にする。3つの値を入れる
  • arrayTextの中身をarrayの2番目に

カウントは0からのため[1]は2番目になる。これで2番目の値bbbになる。

配列を連想配列に変更

次に、配列を連想配列に変更する。

See the Pen array test 03 by イイダリョウ (@i_ryo) on CodePen.

const array = {
    'text1': 'aaa',
    'text2': 'bbb',
    'text3': 'ccc',
};

arrayText.innerHTML = array['text3'];
  • 変数arrayを連想配列に変更する。
  • arrayTextの中身はarraytext3キーの値に

これでtext3キーの値cccになる。

連想配列を配列の入れ子(多次元配列)にしてみる

さらに手を加える。連想配列を配列の入れ子にしてみる。

See the Pen array test 04 by イイダリョウ (@i_ryo) on CodePen.

おや、undefinedになった。

const array = [
    {'text1': 'aaa'},
    {'text2': 'bbb'},
    {'text3': 'ccc'},
];

arrayText.innerHTML = array['text3'];
  • 変数arrayの連想配列をそれぞれ区切って全体を配列に入れてみる
  • arrayTextの中身はtext3のまま

配列の中に連想配列が入れ子になっている多次元構造。それでもキー名が固有なら拾ってもらえるか検証したがダメだった。

多次元配列での呼び出し方に書き換える

以前の記事でやったような多次元配列の書き方に変更する。

See the Pen array test 05 by イイダリョウ (@i_ryo) on CodePen.

JSコード

const array = [
    {'text1': 'aaa'},
    {'text2': 'bbb'},
    {'text3': 'ccc'},
];

arrayText.innerHTML = array[2]['text3'];

arrayTextの中身を3番目のtext3キーにする

多次元配列の書き方だとやはりちゃんと拾ってくれる。

多次元連想配列に書き換える

次に「n番目」ではなく多次元連想配列のキー名で指定する。

See the Pen array test 06 by イイダリョウ (@i_ryo) on CodePen.

JSコード

const array = {
    'text1': {
        'name': 'aaa',
        'age': '13',
    },
    'text2': {
        'name': 'bbb',
        'age': '14',
    },
    'text3': {
        'name': 'ccc',
        'age': '15',
    },
};

arrayText.innerHTML = array['text2']['age'];
  • 変数arrayの中は連想配列。キー名はtext1text2text3
  • text1text2text3キーの値も連想配列で中でnameageキーを設定
  • arrayTextの中身はtext2キーの中のageキー

これで何番目と数えなくてもキー名だけで指定ができるようになった。

キー名を外部の変数で指定できるかテスト

これが一番気になってやってみたかったこと!キー名を外部の変数名で指定する。どういうことか?こちらがご覧ください。

See the Pen array test 07 by イイダリョウ (@i_ryo) on CodePen.

見た目は変わらない。

JSコード

const test = 'text2';

const array = {
    'text1': {
        'name': 'aaa',
        'age': '13',
    },
    'text2': {
        'name': 'bbb',
        'age': '14',
    },
    'text3': {
        'name': 'ccc',
        'age': '15',
    },
};

arrayText.innerHTML = array[test]['age'];
  • 変数testの値はtext2
  • arrayTextのキー名の一つ目をtest

変数testはキー名text2と一致するが単なる文字列。しかし、一致するのでちゃんと値が拾われた!

fot文で配列i番目で連想配列の値を拾う

ここからfor文と多次元連想配列を絡める方法に入る。

See the Pen array test 08 by イイダリョウ (@i_ryo) on CodePen.

HTMLコード

<ul class="array_list">
    <li class="array_text" id="text1">テスト</li>
    <li class="array_text" id="text2">テスト</li>
    <li class="array_text" id="text3">テスト</li>
</ul>
  • .array_listリストの中のliタグにid名#text1#text2#text3を振る。

JSコード

const arrayText = document.querySelectorAll('.array_list li');
  • 変数arrayTextでDOM.array_listのliタグを取得

連想配列を多次元配列に入れる

const array = [
    { 'id': 'text1',
    'name': 'aaa',
    'age': '13',
    },
    { 'id': 'text2',
    'name': 'bbb',
    'age': '14',
    },
    { 'id': 'text3',
    'name': 'ccc',
    'age': '15',
    },
];
  • arrayは連想配列→ただの配列にする
  • text1などのキー名はidキーの値に変更する
const len = arrayText.length;
for (var i =0; i < len; i++) {
    arrayText[i].innerHTML = array[i]['name'];
}
  • 変数lenarrayText(liタグ)の数を取得(=3)
  • for文をlenの数(3回)繰り返す
  • arrayTexti番目の中身をarrayi番目のnameキーの値にする

これでnameキーのそれぞれの値は表示される。和音鍵盤はこの構造になっている。

配列の順番がズレると成立しない

このままだとメンテナンス時に問題が発生し得る。このように。

See the Pen array test 09 by イイダリョウ (@i_ryo) on CodePen.

先ほどは「aaa、bbb、ccc」だった順番が「aaa、ccc、bbb」になっている。

JSコード

const array = [
    { 'id': 'text1',
    'name': 'aaa',
    'age': '13',
    },
    { 'id': 'text3',
    'name': 'ccc',
    'age': '15',
    },
    { 'id': 'text2',
    'name': 'bbb',
    'age': '14',
    },
];
  • 変数array内の配列の順番text2text3を入れ替えている

for文でi番目と順番だけで指定していると配列内の中身の順番が変わったときにズレが発生する。これをなんとかしたい。

多次元連想配列のキー名で指定する

See the Pen array test 10 by イイダリョウ (@i_ryo) on CodePen.

JSコード

const array = {
    'text1': {
        'name': 'aaa',
        'age': '13',
    },
    'text2': {
        'name': 'bbb',
        'age': '14',
    },
    'text3': {
        'name': 'ccc',
        'age': '15',
    },
};
  • 変数arrayの多次元配列を多次元連想配列に戻す

まず配列は再び連想配列に戻す。

JSコード

const len = arrayText.length;
for (var i =0; i < len; i++) {
    const idText = arrayText[i].id;
    arrayText[i].innerHTML = array[idText]['name'];
}
  • for文の中で変数idTextarrayTexti番目のid名を取得
  • arrayTexti番目の中身をarrayidTextキーのnameキーの値にする

先ほど、連想配列のキー名は変数の文字列でも拾ってくれることがわかったので、変数idTextにid名を入れてキー名に当てはめる。id名とキー名は一致するので正しく拾われる。

順番が変わっても問題なし!

連想配列内の順番を変えてみる。

See the Pen array test 11 by イイダリョウ (@i_ryo) on CodePen.

おお!今度はaaa、bbb、cccの順番のまま!

JSコード

const array = {
    'text1': {
        'name': 'aaa',
        'age': '13',
    },
    'text3': {
        'name': 'ccc',
        'age': '15',
    },
    'text2': {
        'name': 'bbb',
        'age': '14',
    },
};
  • 連想配列のtext2キーとtext3キーの順番を入れ替えている

これで、liタグ内のid名と連想配列のキー名が一致さえしていれば、順番が異なっても正しく表示される。メンテナンス性が高まった!(重複や抜けは問題が発生するので中止)

最後に

for文のi番目を参照するのは便利ですが、参照先が複数になる場合に、修正のたびにズレを気にするのが手間に感じたのため、多次元連想配列での指定を検証してみました!

外部の変数でも名前が一致していれば拾われることはわかりましたが、多次元の階層を飛ばして指定することはできないこともわかりました。

今回の検証結果を次回の「和音鍵盤」の方にも反映させていきたいと思います。それではまた!


※参考:ネイティブJSやってみたシリーズ
qiita.com