从 JSON 中删除深层嵌套结构并简化它

问题描述 投票:0回答:1

我有一个具有深层嵌套结构的 JSON,我想要 Javascript/Typescript 中的通用函数来删除多个深层结构。通用就像除了

categories
之外可能有任何父级可能在其键中嵌套。 下面是一个具有深度嵌套的 JSON 示例:-

const nestedObject = {
    "code": {
      "prev": [],
      "current": null
    },
    "updatedAt": {
      "prev": "2024-05-22T12:33:38.834Z",
      "current": "2024-05-23T08:47:11.151Z"
    },
    "categories": {
      "5": {
        "prev": null,
        "current": {
          "id": 12,
          "name": "Value-1"
        }
      },
      "6": {
        "prev": null,
        "current": {
          "id": 13,
          "name": "Value-2"
        }
      },
      "7": {
        "prev": null,
        "current": {
          "id": 14,
          "name": "Value-3"
        }
      },
      "25": {
        "24": {
          "23": {
            "22": {
              "21": {
                "20": {
                  "19": {
                    "18": {
                      "prev": null,
                      "current": {
                        "id": 25,
                        "name": "Value-3"
                      }
                    },
                    "prev": null,
                    "current": {
                      "id": 26,
                      "name": "Value-4"
                    }
                  },
                  "prev": null,
                  "current": {
                    "id": 27,
                    "name": "Value-5"
                  }
                },
                "prev": null,
                "current": {
                  "id": 28,
                  "name": "Value-6"
                }
              },
              "prev": null,
              "current": {
                "id": 29,
                "name": "Value-7"
              }
            },
            "prev": null,
            "current": {
              "id": 30,
              "name": "Value-8"
            }
          },
          "prev": null,
          "current": {
            "id": 31,
            "name": "Value-9"
          }
        },
        "prev": null,
        "current": {
          "id": 32,
          "name": "Value-10"
        }
      }
    }
  };

在示例中,类别中有深度嵌套(即 25->24->23->22->21...)。 我想让它像categories.3和categories.4一样 以下是我希望通用函数给出的预期输出:-

const expectedOutput = {
    "code": {
      "prev": [],
      "current": null
    },
    "updatedAt": {
      "prev": "2024-05-22T12:33:38.834Z",
      "current": "2024-05-23T08:47:11.151Z"
    },
    "categories": {
      "5": {
        "prev": null,
        "current": {
          "id": 12,
          "name": "Value-1"
        }
      },
      "6": {
        "prev": null,
        "current": {
          "id": 13,
          "name": "Value-2"
        }
      },
      "7": {
        "prev": null,
        "current": {
          "id": 14,
          "name": "Value-3"
        }
      },
      "18": {
        "prev": null,
        "current": {
          "id": 25,
          "name": "Value-3"
        }
      },
      "19": {
        "prev": null,
        "current": {
          "id": 26,
          "name": "Value-4"
        }
      },
      "20": {
        "prev": null,
        "current": {
          "id": 27,
          "name": "Value-5"
        }
      },
      "21": {
        "prev": null,
        "current": {
          "id": 28,
          "name": "Value-6"
        }
      },
      "22": {
        "prev": null,
        "current": {
          "id": 29,
          "name": "Value-7"
        }
      },
      "23": {
        "prev": null,
        "current": {
          "id": 30,
          "name": "Value-8"
        }
      },
      "24": {
        "prev": null,
        "current": {
          "id": 31,
          "name": "Value-9"
        }
      },
      "25": {
        "prev": null,
        "current": {
          "id": 32,
          "name": "Value-10"
        }
      }
    }
  };

我发现了一个可以扁平化 JSON 的函数。但这并没有给我预期的输出。这是函数。

const flattenObject = (obj, prefix = '') => {
  let result = {};

  for (let key in obj) {
    if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
      const nested = flattenObject(obj[key], `${prefix}${key}.`);
      result = { ...result, ...nested };
    } else {
      result[`${prefix}${key}`] = obj[key];
    }
  }

  return result;
};
javascript node.js json typescript nested
1个回答
0
投票

这是完成您所提供的 JSON 所需功能的函数:

function flattenNestedObject({ categories, ...rest }) {
  return { 
    // copy all fields except `categories`
    ...rest,
    // overwrite `categories` with a flattened version
    categories: flattenCategories(categories)
  }
}

function flattenCategories(categories) {
    // iterate category keys
    return Object.keys(categories)
      .reduce((result, key) => {
        // extract all nested categories for the given key
        // and return the new accumulated result
        return flattenCategory(categories[key], result, key)
      }, {})
}

/**
 * 
 * @param category category object to flatten
 * @param result accumulated result, the flattened category is assigned here
 * @param catKey key of the category out of which we're pulling the nested categories
 * @returns accumulated result with all current nested categories flattened
 */
function flattenCategory(category, result, catKey) {
  // iterate category's keys
  return Object.keys(category)
    .reduce((acc, key) => {
      // set `catKey` with some placeholder values on the currently
      // acc. result, if it isn't already set
      acc[catKey] ??= { prev: null, current: { id: -1, name: "" } }
      if (key === "prev" || key === "current") {
        // if key is "prev" or "current", just set its value in the acc. result
        acc[catKey][key] = category[key]
        return acc
      } else {
        // key must be related to a nested category, so extract all nested
        // categories for the given key and return the new acc. result
        return flattenCategory(category[key], acc, key)
      }
    }, result)
}

// used like
const flatObj = flattenNestedObject(nestedObject)
© www.soinside.com 2019 - 2024. All rights reserved.