使用按属性排序将平面结构转换为层次结构



我在将平面结构转换为层次结构时遇到了同样的问题,实际上它是从url解决的。但我想让结果按特定字段排序(例如:序列字段(。

let items = [
{
id: 1,
parentId: null,
name: 'A',
sequence: 1
},
{
id: 4,
parentId: 1,
name: 'A-2',
sequence: 2
},
{
id: 5,
parentId: 1,
name: 'A-1',
sequence: 1
},
{
id: 2,
parentId: null,
name: 'B',
sequence: 2
}
];

结果:

[
{
id: 1,
parentId: null,
name: 'A',
sequence: 1,
children: [
{
id: 5,
parentId: 1,
name: 'A-1',
sequence: 1
},
{
id: 4,
parentId: 1,
name: 'A-2',
sequence: 2
},
]
},
{
id: 2,
parentId: null,
name: 'B',
sequence: 2
}
];

是否有任何自定义代码需要我使用,这样我就可以按序列字段对结果进行排序?

/**
* Sort an array of objects by property
* @param {Array} arr Array of Objects
* @param {String} p The property to sort
* @param {boolean} desc Set to true for descend. sort
*/
const sortBy = (arr, p, desc) => arr.sort((a, b) => {
if (desc) [a, b] = [b, a];
const isNum = typeof b[p] === 'number';
return (isNum ? Number(a[p]) - b[p] : String(a[p]).localeCompare(b[p]));
});
/**
* Convert Linear Array to Tree Array
* @param {Array} list to convert
* @param {String} sort the property to sort
*/
const treefy = (list, sort) => {
const map = list.reduce((m, li, i) => {
m[li.id] = i;
li.children = [];
return m;
}, {});
return list.reduce((root, li) => {
const arr = li.parentId ? list[map[li.parentId]].children : root;
arr.push(li);
if (sort) sortBy(arr, sort);
return root;
}, []);
}
// Use like:
const items = [
{id:1, parentId:null, name:"B", sequence:2},
{id:4, parentId:1, name:"A-2", sequence:2},
{id:5, parentId:1, name:"A-1", sequence:1},
{id:2, parentId:null, name:"A", sequence:1}
];
const tree = treefy(items, "sequence");
console.log(tree)

您可以映射出id,然后在映射中迭代,以便将引用添加到某些元素的子元素中:

let items = [{
id: 1,
parentId: null,
name: 'A',
sequence: 1
},
{
id: 4,
parentId: 1,
name: 'A-2',
sequence: 2
},
{
id: 5,
parentId: 1,
name: 'A-1',
sequence: 1
},
{
id: 2,
parentId: null,
name: 'B',
sequence: 2
}
];
function tree(array) {
let mapping = {};
array.forEach(i => {
mapping[i.id] = i; // Maps out the ids
});
array = [];
for (let id in mapping) {
let child = mapping[id];
let {
parentId
} = child;
if (parentId) { // If there is a parent
let parent = mapping[parentId];
if (!parent.children) parent.children = [child];
else parent.children.push(child);
}
}
for (let id in mapping) { // Add to the items ONLY the parents
if (!mapping[id].parentId) array.push(mapping[id]);
}
return array.sort((a, b) => a.id - b.id); // Make sure that the ids are in sequential order
}
console.log(tree(items));

最新更新