【发布时间】:2016-05-21 15:47:44
【问题描述】:
我有一个嵌套对象数组:
[
{_id:1, parent:0, name:'Z'},
{_id:4, parent:0, name:'A'},
{_id:2, parent:1, name:'H'},
{_id:8, parent:2, name:'G'},
{_id:5, parent:4, name:'M'},
{_id:6, parent:4, name:'N'},
{_id:3, parent:1, name:'Z'},
{_id:7, parent:2, name:'L'}
]
我需要对它们进行排序,因为同一级别的节点将按字母顺序排序(asc/desc 可配置),并且所有子节点都应在其父节点之后和其父兄弟节点之前也按字母顺序排序。
比如按asc排序,输出应该是
[
{ _id: 4, parent: 0, name: 'A' },
{ _id: 5, parent: 4, name: 'M' },
{ _id: 6, parent: 4, name: 'N' },
{ _id: 1, parent: 0, name: 'Z' },
{ _id: 2, parent: 1, name: 'H' },
{ _id: 8, parent: 2, name: 'G' },
{ _id: 7, parent: 2, name: 'L' },
{ _id: 3, parent: 1, name: 'Z' }
]
在输出中,4 在 1 之前,因为 A
如果是desc,输出应该是:
[
{ _id: 1, parent: 0, name: 'Z' },
{ _id: 3, parent: 1, name: 'Z' },
{ _id: 2, parent: 1, name: 'H' },
{ _id: 7, parent: 2, name: 'L' },
{ _id: 8, parent: 2, name: 'G' },
{ _id: 4, parent: 0, name: 'A' },
{ _id: 5, parent: 4, name: 'M' },
{ _id: 6, parent: 4, name: 'N' }
]
我尝试实现如下功能。
function sortByHierarchyAndName(arr, sort) {
var i = 0;
j = 0;
t = 0;
parentFound = false;
x = arr.length;
arr2 = [];
//Sort by parent asc first
arr = arr.sort(function(a, b) {
if(a.parent < b.parent) return -1;
if(a.parent > b.parent) return 1;
return 0;
});
for(; i < x; i += 1) {
t = arr2.length;
if(t === 0) arr2.push(arr[i]);
else if(arr[i].parent === 0) {
for(j = 0; j < t; j += 1) {
if(sort === -1) {
if(arr[i].name >= arr2[j].name) arr2.splice(j, 0, arr[i]);
} else {
if(arr[i].name <= arr2[j].name) arr2.splice(j, 0, arr[i]);
}
}
if(arr2.length === t) arr2.push(arr[i]);
}
else {
parentFound = false;
for(j = 0; j < t; j += 1) {
if(arr[i].parent === arr2[j]._id) {
if(j === t - 1) {
arr2.push(arr[i]);
}
parentFound = true;
} else if(arr[i].parent === arr2[j].parent) {
if(sort === -1) {
if(j === t - 1) arr2.push(arr[i]);
else if(arr[i].name >= arr2[j].name) {
arr2.splice(j, 0, arr[i]);
j = t;
}
} else {
if(j === t - 1) arr2.push(arr[i]);
else if(arr[i].name <= arr2[j].name) {
arr2.splice(j, 0, arr[i]);
j = t;
}
}
} else if(arr[i].parent > arr2[j].parent && parentFound) {
arr2.splice(j, 0, arr[i]);
j = t;
}
}
}
}
return arr2;
}
假设 array.sort() 在按父 asc 对长度为 n 的数组进行排序时花费了 f(n) 的时间,我正在对以下实现进行一些性能分析。
最佳情况:f(n) + x * n + y * sum(1 to n/2)*n
最坏情况:f(n) + x * n + y * sum(1 to n)*n;
x - 处理 arr 中任何给定元素的因素。
y - 将 arr 中的任何给定元素与 arr2 中的任何元素进行处理的因素。
如您所见,在这两种情况下,执行持续时间都会随着n 的增长而呈指数增长,所以我想知道是否可以做些什么来改进这一点。
【问题讨论】:
-
很好的问题,但我不确定它是否属于这里。也许在CodeReview?
-
感谢 RobG。我不知道有 CodeReview 社区,将它移过来。
-
array.sort() 不能花费 f(n) 时间,任何排序算法在平均或最坏情况下都不能比 O(n log n) 执行得更好,en.wikipedia.org/wiki/Sorting_algorithm
标签: javascript arrays algorithm sorting quicksort