2013-04-23 76 views
1

我有一个这样的数组:排序阵列递归

var a = [ 
    {id: 1, pid: 0}, 
    {id: 2, pid: 1}, 
    {id: 3, pid: 1}, 
    {id: 4, pid: 2}, 
    {id: 5, pid: 2}, 
    {id: 6, pid: 3}, 
    {id: 7, pid: 3} 
] 

和地图对象是这样的:

var map = { 
    "1": {id: 1, pid: 0}, 
    "2": {id: 2, pid: 1}, 
    "3": {id: 3, pid: 1}, 
    "4": {id: 4, pid: 2}, 
    "5": {id: 5, pid: 2}, 
    "6": {id: 6, pid: 3}, 
    "7": {id: 7, pid: 3} 
} 

我想对它进行排序,以匹配这种模式:

var result = [ 
    {"id": 1, "pid": 0}, 
    {"id": 2, "pid": 1}, 
     {"id": 4, "pid": 2}, 
     {"id": 5, "pid": 2}, 
    {"id": 3, "pid": 1}, 
     {"id": 6, "pid": 3}, 
     {"id": 7, "pid": 3} 
] 

正如你所看到的,这是一个嵌套的树结构。我想在id的匹配下获得pid,最高的是最低的id

有没有什么办法像这样使用一次迭代来排序数组? - 如果没有的话,最好看一个关于如何避开它的例子。

到目前为止,我只有:

a.sort(function(q, w) { return q.pid - w.pid; }); 

而且我想用我的地图,找到使用pid我的父母 - >id,然后排序该键。也可以在我的对象上存储额外的属性。

+1

你缩进,它像它的嵌套,但你实际上没有任何嵌套数组或对象。 – Barmar 2013-04-23 10:12:51

+0

你***不能用一个只知道两个元素的简单比较函数来做到这一点! – phant0m 2013-04-23 10:14:04

+0

@Barmar我认为他知道这一点,基本上,他想要一棵树,然后用预订顺序线性化。 – phant0m 2013-04-23 10:15:19

回答

1

假设有一个根具有PID 0:

var children = {} 
var root = null; 
a.forEach(function(e) { 
    children[e.id] = []; 
}); 

a.forEach(function(e) { 
    if (e.pid === 0) { 
     root = e; 
    } 
    else { 
     children[e.pid].push(e); 
    } 
}); 

var sorted = []; 

function preorder(e) { 
    sorted.push(e); 
    if (children.hasOwnProperty(e.id)) { 
     children[e.id].forEach(preorder); 
    } 
} 
preorder(root); 

结果:

[ 
    {"id":1,"pid":0}, 
    {"id":2,"pid":1}, 
    {"id":4,"pid":2}, 
     {"id":5,"pid":2}, 
    {"id":3,"pid":1}, 
     {"id":6,"pid":3}, 
     {"id":7,"pid":3} 
]