获取一系列关联项

时间:2019-10-13 11:47:42

标签: javascript ecmascript-6

我有一个类别数组,如:

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;
    };

什么是最好的方法?应该使用reduce fn吗?

2 个答案:

答案 0 :(得分:1)

请注意以下内容的调用:

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

表示可能必须迭代整个数组的迭代(最坏的情况)。这具有 O(n)时间复杂度。

代替准备地图,以便您可以在恒定时间内通过其ID识别类别:

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

只要此列表没有更改,您也不必重复创建此地图。有了它后,您可以按ID如下检索类别:

category = map.get(id);

第二,从您的问题来看,尚不清楚您是否真的需要一个数组作为返回值,并且该数组包含指向最根的 whole 路径。如果您真正关心的是获取图像,那么您就不需要该数组,一旦发现null的值非category.image,就应该退出循环,并返回该值。 / p>

答案 1 :(得分:1)

您可以使用_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));