Рекурсивно группировать вложенный массив объектов - PullRequest
0 голосов
/ 06 августа 2020

Ниже приведены данные, которые я получаю от сервера

let tableData = {
  data: [
    {
      data: { name: "two", size: "200", type: "folder" },
      children: []
    },
    {
      data: { name: "two", size: "200", type: "folder" },
      children: []
    },
    {
      data: { name: "two", size: "201", type: "folder" },
      children: []
    },
    {
      data: { name: "one", size: "200", type: "folder" },
      children: []
    },
    {
      data: { name: "one", size: "200", type: "folder" },
      children: []
    },
    {
      data: { name: "one", size: "200", type: "file" },
      children: []
    }
  ]
};

Мне нужно сгруппировать объекты по именам столбцов, хранящимся здесь. Это может быть несколько имен столбцов.

let groupedCols = ["name"];

В примере JSFiddlle мне удалось создать один уровень группировки. Но он ломается, когда я меняю groupedCols на

let groupedCols = ["name", "type"]; or let groupedCols = ["name", "type", "size"]; 

В примере JSFiddle я просматриваю массив groupedCols. В первой итерации я передаю tableDataArr в функцию groupChildren. Но во время второй итерации я хочу передать в него дочерние элементы tableDataArr и т. Д.

Вот ожидаемый объект, который я хочу создать

tableData = {
  data: [
    {
      data: { name: "one", size: "", type: "" }, // level 1 - grouped by name
      children: [
        {
          data: { name: "", size: "", type: "folder" }, // level 2 - grouped by type
          children: [
            {
              data: { name: "one", size: "200", type: "folder" },
            },
            {
              data: { name: "one", size: "200", type: "folder" },
            }
          ]
        },
        {
          data: { name: "", size: "", type: "file" }, // level 2 - grouped by type
          children: [
            {
              data: { name: "one", size: "200", type: "file" }
            }
          ]
        }
      ]
    },
    {
      data: { name: "two", size: "", type: "" }, // level 1 - grouped by name
      children: [
        {
          data: { name: "", size: "", type: "folder" }, // level 2 - grouped by type
          children: [
            {
              data: { name: "two", size: "200", type: "folder" }
            },
            {
              data: { name: "two", size: "200", type: "folder" }
            },
            {
              data: { name: "two", size: "201", type: "folder" }
            }
          ]
        }
      ]
    }
  ],
};

Вот ссылка на JSFiddle - https://jsfiddle.net/jrt1wo6a/1/

Спасибо.

1 Ответ

0 голосов
/ 06 августа 2020

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

const
    groupBy = (array, groups) => array.reduce((r, { data }) => {
        groups
            .reduce((t, k) => {
                let temp = t.find(q => data[k] === q.data[k]);
                if (!temp) t.push(temp = { data: { name: '', size: '', type: '', [k]: data[k] }, children: [] });
                return temp.children;
            }, r)
            .push({ data });
        return r;
    }, []),
    data = [{ data: { name: "two", size: "200", type: "folder" }, children: [] }, { data: { name: "two", size: "200", type: "folder" }, children: [] }, { data: { name: "two", size: "201", type: "folder" }, children: [] }, { data: { name: "one", size: "200", type: "folder" }, children: [] }, { data: { name: "one", size: "200", type: "folder" }, children: [] }, { data: { name: "one", size: "200", type: "file" }, children: [] }];

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