test-task-treerender

Форк
0
/
createTree.js 
85 строк · 4.4 Кб
1
/**
2
 * Функция для создания элементов дерева
3
 * @param {{value: string, level: number, index: number}[]} nodes - Исходная строка, пример: (1 (2 (4 5 6 (7) 108 (9)) 3))
4
 */
5
export function createTree(nodes) {
6
  let tree = ``; // Дерево
7
  const maxValuesLengthOnLevel = []; // Массив из максимальных количеств символов числа на каждом уровне
8
  const verticalLinePositions = []; // Текущии позиции вертикальных линий в строке
9
  const levels = Array.from(new Set(nodes.map((item) => item.level))); // Все уровни из исходных данных
10

11
  // Получаем максимальные количеств символов числа на каждом уровне
12
  for (let i = 0; i < levels.length; i++) {
13
    const value = nodes
14
      .filter((item) => item.level === levels[i])
15
      .map((item) => item.value)
16
      .sort((a, b) => b.length - a.length)[0].length;
17

18
    maxValuesLengthOnLevel.push(value);
19
  }
20

21
  // Формируем данные по каждому узлу
22
  for (let i = 0; i < nodes.length; i++) {
23
    let template = ""; // Шаблон для узла, имеющего дочерние элементы
24
    const node = nodes[i]; // Текущий узел
25
    const nodesOnThisLevel = nodes.filter((item) => item.level === node.level); // Все узлы на данном уровне вложенности
26
    const valueLengthsSum = maxValuesLengthOnLevel
27
      .slice(0, node.level)
28
      .reduce((a, b) => a + b, 0); // Сумма максимальных длин символов ДО текущего уровня вложенности (используется для создания отступов)
29

30
    // Если у узла есть дочерние элементы, добавляем в шаблон строку (n*"-")---+
31
    if (nodes[i + 1] && node.level < nodes[i + 1].level) {
32
      const lastLength = maxValuesLengthOnLevel[node.level];
33
      template = "-".repeat(lastLength - node.value.length) + "---+";
34
    }
35

36
    // Создаем значение строки по текущему узлу (отступы + значение + шаблон)
37
    let treeValue =
38
      " ".repeat(node.level * 3 + valueLengthsSum) + node.value + template;
39

40
    // Добавляем в строку вертикальные линии
41
    for (const position of verticalLinePositions) {
42
      treeValue =
43
        treeValue.slice(0, position) + "|" + treeValue.slice(position + 1);
44
    }
45

46
    // Если на данном уровне есть еще элементы и уровень вложенности следующего элемента больше
47
    if (
48
      nodesOnThisLevel.length !== 1 &&
49
      nodes[i + 1] &&
50
      node.index !== nodesOnThisLevel.at(-1).index &&
51
      node.level < nodes[i + 1].level
52
    ) {
53
      // Находим индекс следующего узла на данном уровне
54
      const nextNodeIndex =
55
        nodesOnThisLevel.findIndex((item) => item.index === node.index) + 1;
56
      // Берем массив узлов от текущего индекса до индекса следующего узла на данном уровне
57
      const nodesBetweenIndex = nodes.slice(
58
        node.index,
59
        nodesOnThisLevel[nextNodeIndex].index
60
      );
61

62
      let validLevels = true; // Валидность уровней узлов
63

64
      // Если хотя бы один узел имеет уровень вложенности меньше текущего, то валидность уровне устанавливается в false
65
      for (const nodeBI of nodesBetweenIndex) {
66
        if (nodeBI.level < node.level) validLevels = false;
67
      }
68

69
      // Если валидность уровней узлов true, то добавляем новую позицию для | в массив verticalLinePositions
70
      if (validLevels) {
71
        verticalLinePositions.push(node.level * 3 + valueLengthsSum);
72
      }
73
    }
74

75
    // Если уровень вложенности будет уменьшаться, убираем последнюю позицию для вертикальной линии
76
    if (nodes[i + 1] && node.level > nodes[i + 1].level) {
77
      verticalLinePositions.pop();
78
    }
79

80
    // Добавляем конечную строку к дереву
81
    tree += `<pre>${treeValue}</pre>`;
82
  }
83

84
  return tree;
85
}
86

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

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