Преобразование плоских данных в трехуровневую иерархию/дерево

В настоящее время я преобразовываю свои плоские данные в иерархию с двумя уровнями, но теперь мне нужно добавить к этим данным дополнительный третий уровень. До сих пор я не смог понять, как изменить существующий метод. Я также открыт для совершенно новых методов.

Вот код, который я сейчас использую для преобразования:

        chartdata = sfdata.data.reduce((acc, {
            items: [cat, val, salesTY, salesLY, unitsTY, unitsLY]
        }) => {
            acc[cat] = acc[cat] || [];
            acc[cat].push({
                name: val,
                salesTY: salesTY,
                salesLY: salesLY,
                unitsTY: unitsTY,
                unitsLY: unitsLY
            });
            return acc;
        }, {});

        // Generate desired output structure.
        chartdata = Object.entries(chartdata).map(([k, v]) => ({
            category: k,
            children: v
        }));

Он сопоставляется с различными категориями, а затем преобразует эту карту в структуру категорий > детей.

А вот скрипт, в котором я использую эту древовидную структуру: http://jsfiddle.net/zt4nhxcw/3/

Я начал новую скрипку здесь с новыми данными о бренде: http://jsfiddle.net/t1uz85b2/

Цель состоит в том, чтобы добавить 3-й уровень. Таким образом, под каждым ребенком 2-го уровня будет Брэнд.

Вот очень небольшой фрагмент того, как поступают данные:

[
  {
    "items": [
      "SSD",
      "PBNA",
      "MOUNTAIN DEW",
      851255.3500000001,
      672407.8399999997,
      782364.9999999991,
      641579.0000000006
    ],
    "hints": {
      "index": 0
    }
  },
  {
    "items": [
      "Energy",
      "RED BULL NORTH AMERICA",
      "RED BULL",
      836632.2299999997,
      654021.2899999995,
      267216,
      214321.00000000015
    ],
    "hints": {
      "index": 1
    }
  },
  {
    "items": [
      "SSD",
      "PBNA",
      "PEPSI",
      478704.02999999974,
      392746.69999999995,
      533557.0000000006,
      457008.0000000001
    ],
    "hints": {
      "index": 4
    }
  },
  {
    "items": [
      "Energy",
      "RED BULL NORTH AMERICA",
      "RED BULL EDITIONS",
      449618.55000000016,
      328150.8999999997,
      162428.9999999999,
      117521.00000000001
    ],
    "hints": {
      "index": 5
    }
  },
  {
    "items": [
      "SSD",
      "CCNA",
      "COKE",
      349685.7899999996,
      276766.95,
      445485.0000000002,
      351214.0000000003
    ],
    "hints": {
      "index": 9
    }
  }
]

И вот окончательная структура, которую я пытаюсь достичь:

[
  {
    "category": "SSD",
    "children": [
      {
        "brand": "PBNA",
        "children": [
          {
            "name": "MOUNTAIN DEW",
            "salesTY": 851255.3500000001,
            "salesLY": 672407.8399999997,
            "unitsTY": 782364.9999999991,
            "unitsLY": 641579.0000000006
          }
        ]
      },
      {
        "brand": "CCNA",
        "children": [
          {
            "name": "COKE",
            "salesTY": 349685.7899999996,
            "salesLY": 276766.95,
            "unitsTY": 445485.0000000002,
            "unitsLY": 351214.0000000003
          }
        ]
      }
    ]
  },
  {
    "category": "Energy",
    "children": [
      {
        "brand": "RED BULL NORTH AMERICA",
        "children": [
          {
            "name": "RED BULL",
            "salesTY": 836632.2299999997,
            "salesLY": 654021.2899999995,
            "unitsTY": 267216,
            "unitsLY": 214321.00000000015
          },
          {
            "name": "RED BULL EDITIONS",
            "salesTY": 449618.55000000016,
            "salesLY": 328150.8999999997,
            "unitsTY": 162428.9999999999,
            "unitsLY": 117521.00000000001
          }
        ]
      }
    ]
  }
]

person CStreet    schedule 29.04.2021    source источник
comment
пожалуйста, добавьте небольшое количество данных к вопросу и желаемому результату данных данных.   -  person Nina Scholz    schedule 29.04.2021
comment
Я обновил вопрос некоторыми данными @NinaScholz   -  person CStreet    schedule 29.04.2021
comment
Приятно решить проблему самостоятельно,   -  person Nur    schedule 29.04.2021


Ответы (1)


Вы можете использовать динамический подход и взять массив с ключами для всех значений и пределом желаемой глубины.

const
    data = [{ items: ["SSD", "PBNA", "MOUNTAIN DEW", 851255.3500000001, 672407.8399999997, 782364.9999999991, 641579.0000000006], hints: { index: 0 } }, { items: ["Energy", "RED BULL NORTH AMERICA", "RED BULL", 836632.2299999997, 654021.2899999995, 267216, 214321.00000000015], hints: { index: 1 } }, { items: ["SSD", "PBNA", "PEPSI", 478704.02999999974, 392746.69999999995, 533557.0000000006, 457008.0000000001], hints: { index: 4 } }, { items: ["Energy", "RED BULL NORTH AMERICA", "RED BULL EDITIONS", 449618.55000000016, 328150.8999999997, 162428.9999999999, 117521.00000000001], hints: { index: 5 } }, { items: ["SSD", "CCNA", "COKE", 349685.7899999996, 276766.95, 445485.0000000002, 351214.0000000003], hints: { index: 9 } }],
    keys = ['category', 'brand', 'name', 'salesTY', 'salesLY', 'unitsTY', 'unitsLY'],
    limit = 2,
    result = data
        .reduce((temp, { items }) => {
            keys
                .slice(0, limit)
                .reduce(function (r, k, i) {
                    if (!r[items[i]]) {
                        r[items[i]] = { _: [] };
                        r._.push({ [k]: items[i], children: r[items[i]]._ });
                    }
                    return r[items[i]];
                }, temp)
                ._
                .push(keys
                    .slice(limit)
                    .reduce((o, k, i) => (o[k] = items[i + limit], o), {})
                );
            return temp;
        }, { _: [] })
        ._;

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

person Nina Scholz    schedule 29.04.2021
comment
Это потрясающе. Спасибо. Я собираюсь попробовать это, чтобы увидеть, смогу ли я получить родительские итоги. - person CStreet; 29.04.2021
comment
Возможно, у вас есть альтернатива Object.fromEntries? Программа, в которой я использую этот код, похоже, не допускает такого синтаксиса :( - person CStreet; 29.04.2021
comment
см. редактирование. - person Nina Scholz; 29.04.2021