LoginSignup
0
0

More than 1 year has passed since last update.

ネストしたObjectをflatにする

Posted at

参考にした記事

結果1(自作 冗長)


export const makeFlatObject = (
  preobj: Record<string, unknown>,
  parentProperty?: string
):Record<string, unknown>  => {
  const initialObject = {};

  const makeObject: Record<string, unknown> = Object.entries(preobj).reduce(
    (previousValue, currentValue, _index, _origin) => {
      const result =
        // 現在の値のvalueがobjectか?
        typeof currentValue[1] === "object"
          ? // objectの場合、その中身は空ではないか?
            Object.keys(currentValue[1] as Record<string, unknown>).length === 0
            ? // 空の場合はvalueに当たる部分が無いとkeyも消されてしまうのでvalueにundefinedを入れてkeyが消えないように保持する
              {
                ...previousValue,
                ...{
                  [`${
                    parentProperty !== undefined
                      ? parentProperty + "_" + currentValue[0]
                      : currentValue[0]
                  }`]: undefined,
                },
              }
            : {
                // からじゃ無い場合は中身のあるobjectなのでmakeFlatObjectに渡してネストした要素がフラットになるまで何回でも回す
                ...previousValue,
                ...makeFlatObject(
                  currentValue[1] as Record<string, unknown>,
                  currentValue[0]
                ),
              }
          : {
              // そもそもobjectじゃない場合、純粋な値のはずなので{key:value}という形になるように整えて前回の値(作成しているflatなobject)に追加する
              ...previousValue,
              ...{
                [`${
                  parentProperty !== undefined
                    ? parentProperty + "_" + currentValue[0]
                    : currentValue[0]
                }`]: currentValue[1],
              },
            };

      return result;
    },
    // initialObject 初期値 ここに引数を用意しなければreduceに渡された配列の0番目になる 一番最初のpreviousValueに入る値
    initialObject
  );

  return makeObject;
};

結果2(メンターから頂いた解答:掲載許可済み)

export const flattenObjWithGenerics = <T extends Record<string, unknown>>(
  obj: T,
  prefix = ''
): Record<string, unknown> => {
  return Object.keys(obj).reduce((acc, k) => {
    const pre = prefix.length ? prefix + '.' : '';
    if (typeof obj[k] === 'object' && obj[k] !== null) {
      Object.assign(
        acc,
        flattenObjWithGenerics(obj[k] as Record<string, unknown>, pre + k)
      );
    } else {
      Object.assign(acc, { [pre + k]: obj[k] });
    }

    return acc;
  }, {});
};

自分の場合Object.entriesを使用してkeyもvalueも取ってきていたがそもそもkeyだけでいい模様
コード量が多くなればなるだけ読み辛くなるのでもっとスマートに書けるようにならないとほんと・・・

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0