将嵌套的 JSON 对象展平并排序到 javascript 中的数组中

Flatten and sort a nested JSON object into an array in javascript

我有一个像这样的对象:

{
  '2021': {
    '08': {
      '26': [{'name': 'Bob', age: 34}, {'name': 'Alice', age: 33}],
      '27': [{'name': 'Jane', age: 21}]
    },
    '09': {
      '03': [{'name': 'John', age: 47}, {'name': 'Sue', age: 36}]
    }
  },
  '2022': {
    '04': {
      '05': [{'name': 'David', age: 26}]
    }
  }
}

我想将此对象展平为 <year, month, day, name, age> 个按日期降序排列的对象数组,因此所需的输出为:

[
  {'year': '2022', 'month': '04', 'day': '05', 'name': 'David', age: 26},
  {'year': '2021', 'month': '09', 'day': '03', 'name': 'John', age: 47},
  {'year': '2021', 'month': '09', 'day': '03', 'name': 'Sue', age: 36},
  {'year': '2021', 'month': '08', 'day': '27', 'name': 'Jane', age: 21},
  {'year': '2021', 'month': '08', 'day': '26', 'name': 'Bob', age: 34},
  {'year': '2021', 'month': '08', 'day': '26', 'name': 'Alice', age: 33},
]

更新:

我按照Nina的逻辑,也拆成两部分,先压平成单深度数组,再排序。展平部分我有一个“更丑陋”的嵌套 for 循环,它也可以工作并使用完全相同的排序代码:

let output = []
for (const year in data) {
  for (const month in data[year]) {
    for (const day in data[year][month]) {
      for (const person of data[year][month][day]) {
        const merged = Object.assign({
          'year': year,
          'month': month,
          'day': day,
        }, person)
        
        output.push(merged)
      }
    }
  }
}

这不是那么灵活,我不确定如何判断性能差异,但我会接受 Nina 的有效答案。

您可以将任务分成两部分,

  1. 通过递归从数据中获取平面数组,
  2. 按需要的键降序排序。

const
    flat = (object, [key, ...keys], values = {}) => Object
        .entries(object)
        .flatMap(([k, v]) => {
            const right = { ...values, [key]: k };
            return Array.isArray(v)
                ? v.map(o => ({ ...right, ...o }))
                : flat(v, keys, right);
        }),
    keys = ['year', 'month', 'day'],
    data = { 2021: { '08': { 26: [{ name: 'Bob', age: 34 }, { name: 'Alice', age: 33 }], 27: [{ name: 'Jane', age: 21 }] }, '09': { '03': [{ name: 'John', age: 47 }, { name: 'Sue', age: 36 }] } }, 2022: { '04': { '05': [{ name: 'David', age: 26 }] } } },
    result = flat(data, keys)
        .sort((a, b) => {
            let r;
            keys.some(k => r = b[k] - a[k]);
            return r;
        });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }