2017-04-21 107 views
2

我有這樣的數組:的Javascript嵌套數組元素得到

"pages": [{ 
    "key": "1", 
    "pages": [{ 
     "key": "2", 
     "pages": [{ 
      "key": "3" 
     }] 
    }, 
     { 
      "key": "4", 
      "pages": [{ 
       "key": "5" 
      }] 

     }] 
}] 

其中鍵1和4是在相同的水平和1包含2含有3和鍵4中包含5我想要的結果是在訂單[3,2,5,1,4]。我已經嘗試了以下遞歸,但我無法獲得正確的順序。

function fnGetAll (oTopDetailPage, array) { 
    var i; 

    for (i=0; i<oTopDetailPage.length; i++) { 
     array.push(oTopDetailPage[i]); 
     if(oTopDetailPage[i].pages) { 
      fnGetAllSubPages(oTopDetailPage[i].pages, array); 
     } 
    } 
    return array; 
} 
+1

你要爲並沒有真正意義的輸出。你能改變你的期望嗎?也許是一個包含父頁面的對象,然後是像{{1:[2,3],4:[5]}}這樣的子對象。爲什麼你需要輸出你要求的? –

+0

如果在對象的「頁面」屬性中添加另一個頁面,其中包含「6」的「關鍵字」,並且「鍵」爲「1」,那麼這些頁面將落在輸出中,爲什麼? –

+0

爲什麼'5'先於'1'? – julekgwa

回答

5

如果你想要一個Depth-first search,你可以先迭代孩子,然後把實際的密鑰。

結果是一個數組,它與給定的數組有一點不同。

function getDepthFirst(object) { 
 
    var result = []; 
 
    object.pages.forEach(function iter(a) { 
 
     Array.isArray(a.pages) && a.pages.forEach(iter); 
 
     result.push(a.key); 
 
    }); 
 
    return result; 
 
} 
 

 
var data = { pages: [{ key: 1, pages: [{ key: 2, pages: [{ key: 3 }] }, { key: 4, pages: [{ key: 5 }] }] }] }; 
 
    
 
console.log(getDepthFirst(data)); // [3, 2, 5, 4, 1]

補遺用於獲取的[3, 5, 2, 4, 1]一個反向級順序遍歷結果,與一個臨時數組,其從相同的水平收集所有數據,並從所有水平恢復的項目陣列,從最高到最低。

該回調函數在實際水平上使用閉包。

function getData(object) { 
 
    var temp = []; 
 
    object.pages.forEach(function iter(level) { 
 
     return function (a) { 
 
      Array.isArray(a.pages) && a.pages.forEach(iter(level + 1)); 
 
      temp[level] = temp[level] || []; 
 
      temp[level].push(a.key); 
 
     }; 
 
    }(0)); 
 
    return temp.reduceRight(function (r, a) { 
 
     return r.concat(a); 
 
    }); 
 
} 
 

 
var data = { pages: [{ key: 1, pages: [{ key: 2, pages: [{ key: 3 }] }, { key: 4, pages: [{ key: 5 }] }] }] }; 
 

 
console.log(getData(data)); // [3, 5, 2, 4, 1]

+0

謝謝:) 是否可以像[3,5,2,4,1]後順序遍歷? – boomcode

+0

@boomcode,這是可能的。名稱是*反轉級別遍歷*,請參閱編輯。 –

1

你的根容器是一點都不奇怪,因爲它是無效的JavaScript。我假設它是{pages: ... }並附上{},但即使這樣也沒有意義,因爲根容器不包含key屬性。

你應該先解決您的節點,這樣你有一個統一的結構,例如

type Node = Node { key: String, pages: [Node] } 

然後實現您的深度優先搜索是微不足道

const dfs = ({key, pages = []}) => 
 
    [...pages.reduce((acc, p) => acc.concat(dfs(p)), []), key] 
 
    
 
const data = { 
 
    "key": "1", 
 
    "pages": [{ 
 
     "key": "2", 
 
     "pages": [{ 
 
      "key": "3" 
 
     }] 
 
    }, 
 
    { 
 
     "key": "4", 
 
     "pages": [{ 
 
      "key": "5" 
 
     }] 
 
    }] 
 
} 
 
    
 
console.log(dfs(data)) 
 
// [ '3', '2', '5', '4', '1' ]


如果您正在通過-h構造數據而且,不要。相反,我建議你製作一個簡單的構造函數來統一構建數據。因爲現在每個節點都保證有keypages屬性,所以我們可以刪除dfspages = []的默認參數值。這比較好,因爲我們可以避免任何可能試圖容納失蹤財產的防禦性編程。

const dfs = ({key, pages}) => 
 
    [...pages.reduce((acc, p) => acc.concat(dfs(p)), []), key] 
 
    
 

 
const makeNode = (key, ...pages) => ({key, pages}) 
 

 
const data = 
 
    makeNode('1', 
 
    makeNode('2', 
 
     makeNode('3')), 
 
    makeNode('4', 
 
     makeNode('5'))) 
 
    
 
console.log(dfs(data)) 
 
// [ '3', '2', '5', '4', '1' ]

+0

hm ... :)看起來更好一些。 –

+0

@NinaScholz <3 <3它只能工作,因爲我強迫根節點包含一個'key'屬性,否則調用我的函數會很奇怪。 – naomik