Suppose we have and array of objects where each object represents a category or a subcategory, like this one:
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}
];
This array represent an example with two categories, where each one of they also have two subcategories.
Now, I'm facing with the problem of sort this array on some custom way. As you can note, the order attribute inside each object is related to the position (or ordering) of the object inside his level of hierarchy. And the relation between categories and subcategories is defined by the atributte parentCategoryId.
The expected sorting I need using as example the previous array of data should be this one:
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}
];
My current approach to solve this problem is based on creating a map to numbers, analyzing the values of the attributes with the following conditions:
- For an object that has the type parent-category we assign the value of
categoryId * 1000. - For an object that has the class child-category we assign the value of
(parentCategoryId * 1000) + order
This logic is shown on the next sort implementation:
let 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 orderedData = data.sort((a, b) =>
{
var aCat = (a.type == "parent-category") ? a.categoryId : a.parentCategoryId;
var aOrder = (a.type == "parent-category") ? 0 : a.order;
var bCat = (b.type == "parent-category") ? b.categoryId : b.parentCategoryId;
var bOrder = (b.type == "parent-category") ? 0 : b.order;
return (aCat * 1000 + aOrder) - (bCat * 1000 + bOrder);
});
console.log(orderedData);
However, and ignoring the fact that the previous implementation works, my question is if there exists a better approach or alternative to solve this problem. I don't like the idea of depend on the mapping to numbers, because, for example, the previous implementation introduces a limitation on the numbers of subcategories (999 in this case) I can sort correctly under each category. Thanks!