2011-07-10 149 views
1

例如:遞歸搜索在JSON或JavaScript對象

[{ 
    id:'our-purpose', 
    title:'Our Purpose', 
    slug:'/our-purpose', 
    backgroundImage:'images/bg-our-purpose.jpg', 
    showInNav:1 
    }, 
    { 
    id:'our-people', 
    title:'Our People', 
    slug:'/our-people', 
    backgroundImage:'images/bg-our-people.jpg', 
    showInNav:1, 
    subpages:[ 
     { 
     id:'attorneys', 
     title:'Attorneys', 
     slug:'/our-people/attorneys', 
     subpages:[ 
      { 
      id:'attorneys-cdb', 
      title:'Attorneys - Carla DeLoach Bryant', 
      slug:'/our-people/attorneys/carla' 
      }, 
      { 
      id:'attorneys-jad', 
      title:'Attorneys - Jordan A. DeLoach', 
      slug:'/our-people/attorneys/jordan' 
      }, 
      { 
      id:'attorneys-shh', 
      title:'Attorneys - Sarah H. Hayford', 
      slug:'/our-people/attorneys/sarah' 
      }, 
      { 
      id:'attorneys-jsp', 
      title:'Attorneys - Jason S. Palmisano', 
      slug:'/our-people/attorneys/jason' 
      }, 
      { 
      id:'attorneys-ldw', 
      title:'Attorneys - Lindsey DeLoach Wagner', 
      slug:'/our-people/attorneys/carla' 
      }, 
     ] 
     }, 
     { 
     id:'legal-support', 
     title:'Legal Support', 
     slug:'/our-people/legal-support', 
     subpages:[ 
      { 
      id:'legal-support-tb', 
      title:'Legal Support - Theolyn Brock', 
      slug:'/our-people/attorneys/theolyn' 
      }, 
      { 
      id:'legal-support-cd', 
      title:'Legal Support - Cheri DeFries', 
      slug:'/our-people/attorneys/cheri' 
      }, 
     ] 
     }, 
//...and so on 

你會發現,你可以做json[1].subpages[0].subpages[0]但我不知道這是怎麼回事有多深是。這是由我的一位設計客戶爲他爲客戶建立的AJAX網站編寫的。我試圖生成除其他事項外導航,需要能夠:

A.解析這個遞歸構建導航(<ul><li><a>...

B.搜索一個匹配的ID。這樣的(但不是遞歸),而忽略了for...in,它只是舉例的緣故)

var matchId(id,json){ 
    for(x in json){ 
    if(json[x].id == id){ var theMatch = json[x]; break; } 
    } 
} 
+1

我不真的在這裏看到一個問題。你似乎明白你需要怎麼做。 – icktoofay

+1

...?嗯,我不知道如何使這個遞歸 –

回答

2

此代碼構建資產淨值爲您提供:

function buildNavForNode(node) { 
    var result = "<li id='" + node.id + "'><a href='" + node.slug + "'>" + node.title + "</a>"; 
    if(node.subpages == undefined) { 
    return result + "</li>"; 
    } else { 
    return result + buildNavForNodes(node.subpages) + "</li>"; 
    } 
} 


function buildNavForNodes(nodes) { 
    var result = "<ul>"; 
    var i = 0; 
    var len = nodes.length; 
    for(; i < len; i++) { 
    result += buildNavForNode(nodes[i]); 
    } 
    return result + "</ul>"; 
} 

這裏是你如何使用它:

var testData = [ 
    { 
    id:'our-purpose', 
    title:'Our Purpose', 
    slug:'/our-purpose', 
    backgroundImage:'images/bg-our-purpose.jpg', 
    showInNav:1 
    }, 
    { 
    id:'our-people', 
    title:'Our People', 
    slug:'/our-people', 
    backgroundImage:'images/bg-our-people.jpg', 
    showInNav:1, 
    subpages:[ 
     { 
     id:'attorneys', 
     title:'Attorneys', 
     slug:'/our-people/attorneys', 
     subpages:[ 
      { 
      id:'attorneys-cdb', 
      title:'Attorneys - Carla DeLoach Bryant', 
      slug:'/our-people/attorneys/carla' 
      }, 
      { 
      id:'attorneys-jad', 
      title:'Attorneys - Jordan A. DeLoach', 
      slug:'/our-people/attorneys/jordan' 
      }, 
      { 
      id:'attorneys-shh', 
      title:'Attorneys - Sarah H. Hayford', 
      slug:'/our-people/attorneys/sarah' 
      }, 
      { 
      id:'attorneys-jsp', 
      title:'Attorneys - Jason S. Palmisano', 
      slug:'/our-people/attorneys/jason' 
      }, 
      { 
      id:'attorneys-ldw', 
      title:'Attorneys - Lindsey DeLoach Wagner', 
      slug:'/our-people/attorneys/carla' 
      }, 
     ] 
     }, 
     { 
     id:'legal-support', 
     title:'Legal Support', 
     slug:'/our-people/legal-support', 
     subpages:[ 
      { 
      id:'legal-support-tb', 
      title:'Legal Support - Theolyn Brock', 
      slug:'/our-people/attorneys/theolyn' 
      }, 
      { 
      id:'legal-support-cd', 
      title:'Legal Support - Cheri DeFries', 
      slug:'/our-people/attorneys/cheri' 
      }, 
     ] 
     } 
    ] 
    } 
]; 

$(function(){ 
    htmlToInsert = buildNavForNodes(testData); 
    console.log(htmlToInsert); 
    $('body').html(htmlToInsert); 
}); 

你可以用遞歸函數做到這一點很容易,但我認爲這很好地描繪職責搞清楚什麼用的頁面收集做和處理本身就是一個單頁之間的分離。

+0

似乎關閉,但這是我的完整飼料:https://gist.github.com/8a9a80f8bccbb0a8136e和代碼停止後OurPeople列出了它的子頁面 –

+0

我已更新代碼。請現在試試。 –

1

這裏是一個開始(在JavaScript和僞代碼的一些混合):

function createMenu(data) { 
    create UL 
    for each item in data { 
     create LI for item in UL 
     if the item has subpages { 
      append createMenu(item.subpages) to the LI 
     } 
    } 
    return UL 
} 

function findByID(data, id) { 
    for each item in data { 
     if(item.id==id) { 
      return the item 
     } 
     if item has subpages { 
      if findByID(item.subpages, id) is not null, return the result 
     } 
    } 
    return null; 
} 
+0

+1漂亮的遞歸。 – kobe

+0

只要注意''for each ... in'只是Mozilla。它不是ECMAScript的一部分。 – user113716

+1

@patrick:我甚至沒有意識到它是有效的JavaScript。我說這是僞代碼... – icktoofay

1
function matchId(id, json){ 
    if (!(json && "object" === typeof json)) { return; } 
    if (json.id === id) { return json; } 
    for (var x in json){ 
    if (Object.hasOwnProperty.call(json, x)) { 
     var result = matchId(id, json[x]); 
     if (result !== undefined) { return result; } 
    } 
    } 
} 
+0

@icktoofay,是的,但這個函數應該無論工作。在http://www.squarefree.com/shell中運行'JSON.stringify(matchId('foo',[{x:{id:'foo',arr:[1,2,3]}}]))'' /shell.html產生'{「id」:「foo」,「arr」:[1,2,3]}'對我來說 –

+0

哦,我忘了'typeof [] ===「object」'。抱歉。 – icktoofay

+0

@icktoofay,是的。 'typeof'令人困惑。有一些新語言版本的建議使其更清晰:http://wiki.ecmascript.org/doku.php?id=harmony:typeof_null&s=typeof+harmony但是IIRC沒有一個地址數組。 –

1

我會試試JSONPath你可以找到代碼here

+0

JSONPath似乎只返回一個匹配項的數組,而不是匹配的對象?我可能會錯誤地使用它。 –

+0

Upvoted,因爲這正是我需要的。 –

0

我所產生的資產淨值與此代碼,因爲我只是想第一級:

$('#sidebar').append('<ul></ul>'); 

for(x in PAGES){ 
    if(PAGES[x].showInNav == 1){ 
    $('#sidebar > ul').append('<li data-id="'+PAGES[x].id+'"><a href="#!'+PAGES[x].slug+'">'+PAGES[x].title+'</a></li>'); 
    if(PAGES[x].subpages){ 
     $('#sidebar > ul > li:last').append('<ul></ul>'); 
     for(y in PAGES[x].subpages){ 
     $('#sidebar > ul > li:last > ul').append('<li data-id="'+PAGES[x].subpages[y].id+'"><a href="#!'+PAGES[x].subpages[y].slug+'">'+PAGES[x].subpages[y].title+'</a></li>'); 
     } 
    } 
    } 
} 

然後,遞歸匹配功能我結束了這段代碼:

var matchKey = function(k,v,j){ 
    k = k || 'id'; //key 
    v = v || ''; //value 
    j = j || PAGES; //json 
    for(x in j){ 
    if(j[x][k] == v){ 
     return j[x]; 
    } 
    if(j[x].subpages){ 
     var result = matchKey(k,v,j[x].subpages); 
     if(result !== undefined){ 
     return result; 
     } 
    } 
    } 
}