对类别和子类别数组进行排序

Shi*_*rsz 5 javascript arrays sorting

假设我们有一个对象数组,其中每个对象代表一个类别或子类别,如下所示:

var data = [
    {type: "parent-category", order: 1, categoryId: 1},
    {type: "parent-category", order: 2, categoryId: 2},
    {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
    {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
];
Run Code Online (Sandbox Code Playgroud)

该数组代表一个具有两个类别的示例,其中每个类别还有两个子类别。

现在,我面临着以某种自定义方式对该数组进行排序的问题。您可以注意到,order每个对象内的属性与该对象在其层次结构级别内的位置(或顺序)相关。类别和子类别之间的关系由属性定义parentCategoryId

我需要使用前面的数据数组作为示例的预期排序应该是这样的:

var data = [
    {type: "parent-category", order: 1, categoryId: 1},
    {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
    {type: "parent-category", order: 2, categoryId: 2},
    {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2},
    {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2}   
];
Run Code Online (Sandbox Code Playgroud)

我当前解决此问题的方法是基于创建数字映射,并在以下条件下分析属性值:

  • 对于具有父类别类型的对象,我们分配值categoryId * 1000
  • 对于具有子类别类的对象,我们分配以下值(parentCategoryId * 1000) + order

该逻辑在下一个排序实现中显示:

var data = [
    {type: "parent-category", order: 1, categoryId: 1},
    {type: "parent-category", order: 2, categoryId: 2},
    {type: "child-category", order: 1, categoryId: 3, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 4, parentCategoryId: 1},
    {type: "child-category", order: 2, categoryId: 5, parentCategoryId: 2},
    {type: "child-category", order: 1, categoryId: 6, parentCategoryId: 2}
];
Run Code Online (Sandbox Code Playgroud)

然而,忽略以前的实现有效的事实,我的问题是是否存在更好的方法或替代方案来解决这个问题。我不喜欢依赖于数字映射的想法,因为例如,以前的实现引入了对子类别数量的限制(999在本例中),我可以在每个类别下正确排序。谢谢!

kem*_*ica 4

使用 Array#filter Array#sort 和 Array#map 的简单高性能解决方案

var data=[{type:"parent-category",order:1,categoryId:1},{type:"parent-category",order:2,categoryId:2},{type:"child-category",order:1,categoryId:3,parentCategoryId:1},{type:"child-category",order:2,categoryId:4,parentCategoryId:1},{type:"child-category",order:2,categoryId:5,parentCategoryId:2},{type:"child-category",order:1,categoryId:6,parentCategoryId:2}]

let res = data
  .filter(({type}) => type === "parent-category")
  .sort((a,b) => a.order - b.order)
  .reduce((acc, curr) =>{
    const children = data
      .filter(({parentCategoryId}) => parentCategoryId === curr.categoryId)
      .sort((a,b) => a.order - b.order);

    acc.push(curr, ...children);
    return acc;
  }, []);

console.log(res);
Run Code Online (Sandbox Code Playgroud)