2013-04-23 74 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} 
]