Qiitaにログインして、便利な機能を使ってみませんか?

0
0

記事を削除する

一度削除した記事は復旧できません。

この記事の編集中の下書きも削除されます。

削除してよろしいですか?

JavaScriptでネストの深いObjectの初期化を一括で行う

投稿日

やりたいこと

以下のようにネストが深いハッシュの場合、親がundefiendになるので一括で初期化ができない。hash['a']のキーが存在するのか不明な時はめんどくさい。

const hash = {}
hash['a']['b']['c'] = 1

image.png

愚直にやるなら

各階層でキーが存在するかを確認し初期化する必要がある。めんどくさい。

const hash = {}
if(!hash['a']) hash['a'] = {}
if(!hash['a']['b']) hash['a']['b'] = {}
hash['a']['b']['c'] = 1

image.png

再帰関数を使う

再帰関数を使って初期化していく方法。

この関数には問題があります。後半の「この解決策の問題点」を必ず参照してください

// hashオブジェクトに対して値が無ければ初期化する関数
const setProperty = (obj, ...keys) => {
  const key = keys[0]

  // 次のキーが無ければ終了
  if (!keys[1]) {
    obj[key] = {}
    return
  }

  // プロパティがなければ初期化する
  if (!obj[key]) {
    // 次の値が数値ならば配列にする
    if (Number.isInteger(keys[1])) {
      obj[key] = []
    } else {
      obj[key] = {}
    }
  }

  setProperty(obj[key], ...keys.slice(1))
}

使用例

image.png

解説

三点リーダ

「...」は可変長引数。使用例のようにsetPropertyに複数の引数を与えることができる

Number.isInteger

数値かどうか判定する。'0'は文字列、0は数値と分けてくれる。

.slice(1)

部分配列を返す。1なので、2番目の値以降の部分配列にする

この解決策の問題点

objは引数で取っているが、関数内で更新している。そのためESLintのno-param-reassignが発生してしまう。解決策求ム。

まとめ

あとちょっとでもっといい感じにできそう。良いアイディアお待ちしています。

0
0
1

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
  3. ダークテーマを利用できます
ログインすると使える機能について
YoshitakeHiroki

@YoshitakeHiroki(吉竹 弘喜)

2011年からエンジニアやってます。2022年現在は福岡在住です。PHP/Ruby/C#/Vueが得意です。おいしいお酒とご飯があればどこへでも向かいます。音楽好き。ライブ狂。
layered
私たちは、人に寄り添うテクノロジーで医療インターフェースを研究・実装し、「共創する医療」をつくる会社です。

コメント

akebi_mh
@akebi_mh
(編集済み)

Object.assign()では駄目でしょうか。

const hash = {};
Object.assign(hash, {a:{b:{c:1}}});
console.log(hash['a']['b']['c']); // 1
0

いいね以上の気持ちはコメントで

記事投稿キャンペーン開催中

0
0

記事を削除する

一度削除した記事は復旧できません。

この記事の編集中の下書きも削除されます。

削除してよろしいですか?

ログインして続ける

ソーシャルアカウントでログイン・新規登録

メールアドレスでログイン・新規登録