我有一系列对象,如:
[
{
id: 8,
name: 'Shirts',
slug: 'shirts',
parent_id: null
},
{
id: 9,
name: 'Pants',
slug: 'pants',
parent_id: null
},
{
id: 10,
name: 'Vintage Prints',
slug: 'vintage-prints',
parent_id: 8
},
{
id: 11,
name: 'Cotton Tee',
slug: 'cotton-tee',
parent_id: 8
},
{
id: 12,
name: 'Business Khakis',
slug: 'business-khakis',
parent_id: 9
}
]
我需要的是:
[
{
id: 9,
name: 'Pants',
slug: 'pants',
parent_id: null
},
{
id: 12,
name: 'Business Khakis',
slug: 'business-khakis',
parent_id: 9
},
{
id: 8,
name: 'Shirts',
slug: 'shirts',
parent_id: null
},
{
id: 11,
name: 'Cotton Tee',
slug: 'cotton-tee',
parent_id: 8
},
{
id: 10,
name: 'Vintage Prints',
slug: 'vintage-prints',
parent_id: 8
}
]
我做了什么: 这看起来应该有效:
_.orderBy(categories, ['parent_id', 'name'], ['asc', 'asc']);
但是我想知道parent_id中的空值是否正在弄乱它。
修改 内部和外部结果也应按字母顺序排序。所以裤子在外层衬衫之前和Cotton Tee之前的Vintage Tints在儿童层。请记住,这可能是无限层,棉花Tee可能是父母等等。
如果每个已排序的对象都可以接收索引或级别,以便您知道它嵌套了多少级别,那也很棒。
答案 0 :(得分:0)
单一排序不起作用,因为父子关系在排序数据时不予考虑。
此解决方案分为三个部分:
按字母顺序对数据进行排序,因为以下树是按插入顺序构建的。
使用给定的关系构建树。
遍历树并获取已排序的平面数据。
var data = [{ id: 8, name: 'Shirts', slug: 'shirts', parent_id: null }, { id: 9, name: 'Pants', slug: 'pants', parent_id: null }, { id: 10, name: 'Vintage Prints', slug: 'vintage-prints', parent_id: 8 }, { id: 11, name: 'Cotton Tee', slug: 'cotton-tee', parent_id: 8 }, { id: 12, name: 'Business Khakis', slug: 'business-khakis', parent_id: 9 }]
.sort(function (a, b) {
return a.name.localeCompare(b.name);
}),
tree = function (data, root) {
var r = [], o = {};
data.forEach(function (a) {
o[a.id] = { data: a, children: o[a.id] && o[a.id].children };
if (a.parent_id === root) {
r.push(o[a.id]);
} else {
o[a.parent_id] = o[a.parent_id] || {};
o[a.parent_id].children = o[a.parent_id].children || [];
o[a.parent_id].children.push(o[a.id]);
}
});
return r;
}(data, null),
sorted = tree.reduce(function traverse(r, a) {
return r.concat(a.data, (a.children || []).reduce(traverse, []));
}, [])
console.log(sorted);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var data = [{ id: 8, name: 'Shirts', slug: 'shirts', parent_id: null }, { id: 9, name: 'Pants', slug: 'pants', parent_id: null }, { id: 10, name: 'Vintage Prints', slug: 'vintage-prints', parent_id: 8 }, { id: 11, name: 'Cotton Tee', slug: 'cotton-tee', parent_id: 8 }, { id: 12, name: 'Business Khakis', slug: 'business-khakis', parent_id: 9 }]
.sort(function (a, b) {
return a.name.localeCompare(b.name);
}),
tree = function (data, root) {
var r = [], o = {};
data.forEach(function (a) {
o[a.id] = { data: a, children: o[a.id] && o[a.id].children };
if (a.parent_id === root) {
r.push(o[a.id]);
} else {
o[a.parent_id] = o[a.parent_id] || {};
o[a.parent_id].children = o[a.parent_id].children || [];
o[a.parent_id].children.push(o[a.id]);
}
});
return r;
}(data, null),
sorted = tree.reduce(function traverse(level) {
return function (r, a) {
a.data.level = level
return r.concat(a.data, (a.children || []).reduce(traverse(level + 1), []));
};
}(0), []);
console.log(sorted);
.as-console-wrapper { max-height: 100% !important; top: 0; }