@HealSpirit

Как создать дерево из массива (колонки и таблицы, к которым они принадлежат)?

Всем привет.
Имеются данные с сервера, список колонок и таблицы, к которым они принадлежат:
const columnList = [
  { id: 11, name: "Колонка 1", table: { id: 27, name: "Таблица 1" } },
  { id: 12, name: "Колонка 2", table: { id: 29, name: "Таблица 3" } },
  { id: 13, name: "Колонка 3", table: { id: 28, name: "Таблица 2" } },
  { id: 14, name: "Колонка 4", table: { id: 28, name: "Таблица 2" } },
  { id: 15, name: "Колонка 5", table: { id: 27, name: "Таблица 1" } },
  { id: 16, name: "Колонка 6", table: { id: 29, name: "Таблица 3" } },
];

Нужно получить другой массив, где родителями будут таблицы, а детьми - их колонки. Для уникализации ключей было неплохо объединить название и id:
const result = [
  {
    key: "Таблица 1-27",
    title: "Таблица 1",
    children: [
      { key: "Колонка 1-11", title: "Колонка 1" },
      { key: "Колонка 5-15", title: "Колонка 5" },
    ],
  },
  {
    key: "Таблица 3-29",
    title: "Таблица 3",
    children: [
      { key: "Колонка 2-12", title: "Колонка 2" },
      { key: "Колонка 6-16", title: "Колонка 6" },
    ],
  },
  {
    key: "Таблица 2-28",
    title: "Таблица 2",
    children: [
      { key: "Колонка 3-13", title: "Колонка 3" },
      { key: "Колонка 4-14", title: "Колонка 4" },
    ],
  },
];
  • Вопрос задан
  • 107 просмотров
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
const createItem = obj => ({ key: `${obj.name}-${obj.id}`, title: obj.name });

const result = Object.values(columnList.reduce((acc, n) => {
  (acc[n.table.id] ??= {
    ...createItem(n.table),
    children: [],
  }).children.push(createItem(n));

  return acc;
}, {}));
Ответ написан
Seasle
@Seasle Куратор тега JavaScript
const combine = ({
  entries = [],
  createItem = entry => entry,
  getParent = entry => entry,
  getChild = entry => entry,
  getKey = entry => entry.id
}) => {
  const cache = new Map();
  
  return entries.reduce((accumulator, entry) => {
    const parent = getParent(entry);
    const child = getChild(entry);
    const key = getKey(parent);
    
    if (!cache.has(key)) {
      const branch = {
        ...createItem(parent),
        children: []
      };
      cache.set(key, branch);
      accumulator.push(branch);
    }
    
    cache.get(key).children.push(createItem(child));
    
    return accumulator;
  }, []);
};

const result = combine({
  entries: columnList,
  createItem: entry => ({
    key: `${entry.name}-${entry.id}`,
    title: entry.name
  }),
  getParent: entry => entry.table
});
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы