的Javascript嵌套数组元素得到
我有这样的数组:的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;
}
如果你想要一个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]
谢谢:) 是否可以像[3,5,2,4,1]后顺序遍历? – boomcode
@boomcode,这是可能的。名称是*反转级别遍历*,请参阅编辑。 –
你的根容器是一点都不奇怪,因为它是无效的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构造数据而且,不要。相反,我建议你制作一个简单的构造函数来统一构建数据。因为现在每个节点都保证有key
和pages
属性,所以我们可以删除dfs
中pages = []
的默认参数值。这比较好,因为我们可以避免任何可能试图容纳失踪财产的防御性编程。
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' ]
hm ... :)看起来更好一些。 –
@NinaScholz naomik
你要为并没有真正意义的输出。你能改变你的期望吗?也许是一个包含父页面的对象,然后是像{{1:[2,3],4:[5]}}这样的子对象。为什么你需要输出你要求的? –
如果在对象的“页面”属性中添加另一个页面,其中包含“6”的“关键字”,并且“键”为“1”,那么这些页面将落在输出中,为什么? –
为什么'5'先于'1'? – julekgwa