Как преобразовать плоскую структуру данных в древовидную структуру? - PullRequest
0 голосов
/ 08 ноября 2018

Допустим, у меня есть две вспомогательные функции, преобразующие плоский массив {} в древовидную структуру. Рассмотрим следующие плоские данные:

const data = [
     {
            "ID": 1,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 2,
            "Tier_1": "DataSource1",
            "Tier_2": "Financial",
            "Tier_3": "General",
        },
        {
            "ID": 3,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 4,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 5,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "Management Plan",
        }
]

Данные содержат три строки некоторой иерархической информации, которую я хотел бы преобразовать в древовидную структуру, например так (ожидаемый результат):

(последние дочерние элементы являются фактическими объектами БД, но распределены по дереву)

const output = {
  "DataSource1: {
    "Area": {
        {
            "ID": 1,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
        {
            "ID": 3,
            "Tier_1": "DataSource1",
            "Tier_2": "Area",
            "Tier_3": "General",
        },
      },
      "Financial": [
        {
            "ID": 2,
            "Tier_1": "DataSource1",
            "Tier_2": "Financial",
            "Tier_3": "General",
        },
      ]
  },
  "DataSource2: {
      "Area": [
          {
            "ID": 4,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "General",
          },
          {
            "ID": 5,
            "Tier_1": "DataSource2",
            "Tier_2": "Area",
            "Tier_3": "Management Plan",
          }
       ]
      }
  }
}

Мне действительно удалось создать функции для достижения этой цели, но я не настолько гибок (глубина / затемнение фиксировано, что указано в названии каждой функции)

Функция, возвращающая 2-мерное дерево:

const getDataCategoriesTwoDim = (data, mainCategory) => {
  const dataFields = [...data];
  let map = {};

  for (let i = 0; i < dataFields.length; i += 1) {
    const currentField = dataFields[i];
    const currentCategory = currentField[mainCategory];

    if (!map[currentCategory]) {
      map[currentCategory] = [];
    }
    map[currentCategory].push(currentField);
  }

  return map;
};

Функция, возвращающая трехмерное дерево:

const getDataCategoriesThreeDim = (data, mainCategory, subCategory) => { // DIFF
  const dataFields = [...data];
  let map = {};

  for (let i = 0; i < dataFields.length; i += 1) {
    const currentField = dataFields[i];
    const currentCategory = currentField[mainCategory];
    const currentSubcategory = currentField[subCategory]; // DIFF

    if (!map[currentCategory]) {
      map[currentCategory] = {}; /DIFF
    }
    if (!map[currentCategory][currentSubcategory]) { // DIFF
      map[currentCategory][currentSubcategory] = []; // DIFF
    } // DIFF
    map[currentCategory][currentSubcategory].push(currentField); // DIFF
  }

  return map;
};

Вы можете позвонить и так, и получить ожидаемый результат:

  getDataCategoriesTwoDim(data, 'Tier_2');
  getDataCategoriesThreeDim(data, 'Tier_2', 'Tier_3');

Как видите, повторений кода и копирования очень много. Я отметил различия в комментариях. Как я могу переписать код в одну функцию, чтобы я мог установить 2, 3 или более измерений?

1 Ответ

0 голосов
/ 08 ноября 2018

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

const
    groupBy = (data, keys) => data.reduce((r, o) => {
        keys
            .reduce((p, k, i, a) =>
                 p[o[k]] = p[o[k]] || (i + 1 === a.length ? [] : {}), r)
            .push(o);
        return r;
    }, Object.create(null)),
    data = [{ ID: 1, Tier_1: "DataSource1", Tier_2: "Area", Tier_3: "General" }, { ID: 2, Tier_1: "DataSource1", Tier_2: "Financial", Tier_3: "General" }, { ID: 3, Tier_1: "DataSource1", Tier_2: "Area", Tier_3: "General" }, { ID: 4, Tier_1: "DataSource2", Tier_2: "Area", Tier_3: "General" }, { ID: 5, Tier_1: "DataSource2", Tier_2: "Area", Tier_3: "Management Plan" }],
    result1 = groupBy(data, ["Tier_1", "Tier_2"]),
    result2 = groupBy(data, ["Tier_1", "Tier_2", "Tier_3"]);

console.log(result1);
console.log(result2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...