Получение массива связанных элементов - PullRequest
1 голос
/ 13 октября 2019

У меня есть массив категорий, например:

0: {_id: 1, image: "/static/categories/apartment.png", name: "apartments", properties: Array(2), rootCategoryId: null, …}
1: {_id: 2, image: "/static/categories/car.png", name: "cars", properties: Array(1), rootCategoryId: null, …}
2: {_id: 3, image: "/static/categories/dress.png", name: "cloathes", properties: Array(1), rootCategoryId: null, …}
3: {_id: 4, image: "/static/categories/fridge.png", name: "electronicsAndGadgets", properties: Array(1), rootCategoryId: null, …}
4: {_id: 99, image: "/static/categories/phone.png", name: "smartPhones", properties: Array(0), rootCategoryId: 4, …}
5: {_id: 100, image: "/static/categories/shoes.png", name: "shoes", properties: Array(0), rootCategoryId: 3, …}
6: {_id: 1000, image: null, name: "sneakers", properties: Array(0), rootCategoryId: 100, …}
7: {_id: 1001, image: null, name: "sandals", properties: Array(0), rootCategoryId: 100, …}

Другими словами.

Root category (image: '../png', rootCategoryId: null)

Sub categories (image: '../png' OR null, rootCategoryId: ID)


1 (root) -> 100 (sub1) -> 1000 (sub2)

Поскольку root всегда имеет изображение, а иногда подкатегории не имеют изображения,Я пытаюсь сделать обратный поиск, пока не найду картинку. Создал эту функцию, чтобы получить связанные категории, но я думаю, что это можно сделать лучше:

    export const getCategoryImageByByCategoryId = id => {
      if (!store) return null;
      const getCategory = (id) => _.find(categoriesList, category => category._id === id);
      const state = store.getState();
      const categoriesList = state.categories.categoriestList;
      let currentCategory = getCategory(id);
      const result = [currentCategory];
      while (currentCategory !== null) {
        const nextId = currentCategory.rootCategoryId;
        if (!nextId) {
          currentCategory = null;
        } else {
          currentCategory = getCategory(nextId);
          result.push(currentCategory);
        }
      }
      return result;
    };

Каков наилучший способ сделать это? Следует использовать уменьшить FN?

Ответы [ 2 ]

1 голос
/ 13 октября 2019

Вы можете создать объект с _id в качестве ключа и вызывать функцию, пока не получите изображение.

function getCategoryImageByByCategoryId(id) {
    return reference[id].image
        || getCategoryImageByByCategoryId(reference[id].rootCategoryId);
}

var data = [{ _id: 1, image: "/static/categories/apartment.png", name: "apartments", properties: [], rootCategoryId: null }, { _id: 2, image: "/static/categories/car.png", name: "cars", properties: [], rootCategoryId: null }, { _id: 3, image: "/static/categories/dress.png", name: "cloathes", properties: [], rootCategoryId: null }, { _id: 4, image: "/static/categories/fridge.png", name: "electronicsAndGadgets", properties: [], rootCategoryId: null }, { _id: 99, image: "/static/categories/phone.png", name: "smartPhones", properties: [], rootCategoryId: 4 }, { _id: 100, image: null, name: "shoes", properties: [], rootCategoryId: 3 }, { _id: 1000, image: null, name: "sneakers", properties: [], rootCategoryId: 100 }, { _id: 1001, image: null, name: "sandals", properties: [], rootCategoryId: 100 }],
    reference = data.reduce((r, o) => {
        r[o._id] = o;
        return r;
    }, {});

console.log(getCategoryImageByByCategoryId(1000));
1 голос
/ 13 октября 2019

Обратите внимание, что вызов следующего:

const getCategory = (id) => _.find(categoriesList, category => category._id === id);

Представляет итерацию, которая вполне может потребоваться для итерации всего массива (наихудший случай). Это имеет O (n) сложность времени.

Вместо этого подготовьте карту, чтобы вы могли идентифицировать категорию по ее идентификатору в постоянное время:

let map = new Map(state.categories.categoriesList.map(category => [category._id, category]));

Покатак как этот список не меняется, вам не нужно повторять создание этой карты. Как только он у вас есть, вы можете просто извлечь категорию по идентификатору следующим образом:

category = map.get(id);

Во-вторых, из вашего вопроса не ясно, что вам действительно нужен массив в качестве возвращаемого значения, и тот, который содержит весь путь к самому корню. Если вы действительно хотите получить изображение, тогда вам не нужен этот массив, и вы должны выйти из цикла, как только вы найдете не null значение для category.image, и вернуть его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...