деревья, дать каждому элементу id, найти у каждого элемента id, JavaScript

function putIdFilters(filters_) {

  const filters = filters_.slice();

  let num = 0;
  preOrder(filters);

  function preOrder(node) {
    if (node == null) {
      return;
    }

    if (node.length === 1) {
      node[0].id = ++num;
      return;
    }

    node.forEach(item => {
      item.id = ++num;
      preOrder(item.children);
    });
  }

  return filters;

}

function findById(id, where) {
  for (let item of where) {
    if (item.id === id) {
      return item;
    } else if (item.children) {
      return findById(id, item.children);
    }
  }
}

const filters = [{
    item: 'Сегмент',
    type: 'checkbox',
    children: [{
        item: 'Малый бизнес',
        type: 'checkbox'
      },
      {
        item: 'Средний бизнес',
        type: 'checkbox'
      },
    ]
  },
  {
    item: 'Продукт или канал',
    type: 'checkbox',
    children: [{
        item: 'РКО',
        children: [{
            item: 'Ведение счёта',
            type: 'checkbox'
          },
          {
            item: 'Открытие счёта',
            type: 'checkbox'
          },
          {
            item: 'Закрытие счёта',
            type: 'checkbox'
          },
          {
            item: 'Платежи и переводы',
            type: 'checkbox'
          },
          {
            item: 'Кассовые операции',
            type: 'checkbox'
          }
        ]
      },
      {
        item: 'Кредиты и гарантии',
        type: 'checkbox',
        children: [{
            item: 'Кредиты в целом',
            type: 'checkbox'
          },
          {
            item: 'Экспресс кредитование',
            type: 'checkbox'
          },
          {
            item: 'Овердрафт',
            type: 'checkbox'
          }
        ]
      },
      {
        item: 'Бизнес-портал',
        type: 'checkbox'
      },
      {
        item: 'Офисы',
        type: 'checkbox'
      },
      {
        item: 'Банкоматы',
        type: 'checkbox'
      }
    ]
  },
  {
    item: 'Тематика',
    type: 'checkbox',
    children: [{
        item: 'Медленное / несвоевременное обслуживание',
        type: 'checkbox'
      },
      {
        item: 'Невыгодные условия / тарифы',
        type: 'checkbox'
      },
      {
        item: 'Проблемы с информированием',
        type: 'checkbox'
      },
      {
        item: 'Блокировки / ограничения',
        type: 'checkbox'
      }
    ]
  },
  {
    item: 'Источник',
    type: 'checkbox',
    children: [{
        item: 'Опросы',
        type: 'checkbox'
      },
      {
        item: 'Жалобы и претензии',
        type: 'checkbox'
      },
      {
        item: 'Блокировки / ограничения',
        type: 'checkbox'
      }
    ]
  },
  {
    item: 'Отзывы',
    type: 'checkbox',
    children: [{
        item: 'Негативные',
        type: 'checkbox'
      },
      {
        item: 'Оценка',
        type: 'slider',
        slider: {
          from: 0,
          to: 10
        }
      }
    ]
  },
  {
    item: 'Не отзывы',
    type: 'checkbox',
    children: [{
        item: 'Негативные',
        type: 'checkbox'
      },
      {
        item: 'Оценка по не отзывам',
        type: 'slider',
        slider: {
          from: 0,
          to: 14
        }
      }
    ]
  }
];

const filtersWithId = putIdFilters(filters);
const itemFind = findById(3, filtersWithId);
console.log(itemFind);

У меня есть две функции, putIdFilters, которая пробегает по каждому элементу в дереве и даёт им уникальные id, а также findById, которая находит в дереве элемент по id и возвращает его. Можно ли как-то ускорить этот процесс, чтобы это легче происходило для браузера? Я планирую findById использовать по нескольку раз


Ответы (1 шт):

Автор решения: Михаил Камахин

Я предполагаю, что хорошим решением будет использовать Map, чтобы искать по id

function putIdFilters(filters_) {

  const filters = filters_.slice();
  const map = new Map();

  let num = 0;
  preOrder(filters);

  function preOrder(node) {
    if (node == null) {
      return;
    }

    if (node.length === 1) {
      node[0].id = ++num;
      map.set(node[0].id, node[0]);
      return;
    }

    node.forEach(item => {
      item.id = ++num;
      map.set(item.id, item);
      preOrder(item.children);
    });
  }

  return {
    arr: filters,
    map: map
  };

}

const filters = [{
    item: 'Сегмент',
    type: 'checkbox',
    children: [{
        item: 'Малый бизнес',
        type: 'checkbox'
      },
      {
        item: 'Средний бизнес',
        type: 'checkbox'
      },
    ]
  },
  {
    item: 'Продукт или канал',
    type: 'checkbox',
    children: [{
        item: 'РКО',
        children: [{
            item: 'Ведение счёта',
            type: 'checkbox'
          },
          {
            item: 'Открытие счёта',
            type: 'checkbox'
          },
          {
            item: 'Закрытие счёта',
            type: 'checkbox'
          },
          {
            item: 'Платежи и переводы',
            type: 'checkbox'
          },
          {
            item: 'Кассовые операции',
            type: 'checkbox'
          }
        ]
      },
      {
        item: 'Кредиты и гарантии',
        type: 'checkbox',
        children: [{
            item: 'Кредиты в целом',
            type: 'checkbox'
          },
          {
            item: 'Экспресс кредитование',
            type: 'checkbox'
          },
          {
            item: 'Овердрафт',
            type: 'checkbox'
          }
        ]
      },
      {
        item: 'Бизнес-портал',
        type: 'checkbox'
      },
      {
        item: 'Офисы',
        type: 'checkbox'
      },
      {
        item: 'Банкоматы',
        type: 'checkbox'
      }
    ]
  },
  {
    item: 'Тематика',
    type: 'checkbox',
    children: [{
        item: 'Медленное / несвоевременное обслуживание',
        type: 'checkbox'
      },
      {
        item: 'Невыгодные условия / тарифы',
        type: 'checkbox'
      },
      {
        item: 'Проблемы с информированием',
        type: 'checkbox'
      },
      {
        item: 'Блокировки / ограничения',
        type: 'checkbox'
      }
    ]
  },
  {
    item: 'Источник',
    type: 'checkbox',
    children: [{
        item: 'Опросы',
        type: 'checkbox'
      },
      {
        item: 'Жалобы и претензии',
        type: 'checkbox'
      },
      {
        item: 'Блокировки / ограничения',
        type: 'checkbox'
      }
    ]
  },
  {
    item: 'Отзывы',
    type: 'checkbox',
    children: [{
        item: 'Негативные',
        type: 'checkbox'
      },
      {
        item: 'Оценка',
        type: 'slider',
        slider: {
          from: 0,
          to: 10
        }
      }
    ]
  },
  {
    item: 'Не отзывы',
    type: 'checkbox',
    children: [{
        item: 'Негативные',
        type: 'checkbox'
      },
      {
        item: 'Оценка по не отзывам',
        type: 'slider',
        slider: {
          from: 0,
          to: 14
        }
      }
    ]
  }
];

const filtersWithId = putIdFilters(filters);
const find2 = filtersWithId.map.get(2);
console.log(find2);

→ Ссылка