Javascript 从嵌套对象树获取路径
我现在遇到了一个问题,刚开始的时候似乎不难解决,但现在我遇到了几个小时,所以我们开始: 给定此对象数组:Javascript 从嵌套对象树获取路径,javascript,recursion,coffeescript,Javascript,Recursion,Coffeescript,我现在遇到了一个问题,刚开始的时候似乎不难解决,但现在我遇到了几个小时,所以我们开始: 给定此对象数组: groups = [ { name: 'Custard apple', slug: 'custard-apple', children: [ { name: 'Vanilla', slug: 'vanilla', children: [ { name: 'Str
groups = [
{
name: 'Custard apple',
slug: 'custard-apple',
children: [
{
name: 'Vanilla',
slug: 'vanilla',
children: [
{
name: 'Strawberry',
slug: 'strawberry',
children: []
}, {
name: 'Pineapple',
slug: 'pineapple',
children: []
}
]
}, {
name: 'Chocolate',
slug: 'chocolate',
children: []
}
]
}, {
name: 'Raspberry',
slug: 'raspberry',
children: []
}, {
name: 'Lemon',
slug: 'lemon',
children: [
{
name: 'Orange',
slug: 'orange',
children: [
{
name: 'Coconut',
slug: 'coconut',
children: []
}
]
}, {
name: 'Almond',
slug: 'almond',
children: []
}
]
}
];
我试图找到一个函数,该函数通过一个给定的slug
为我提供一个对象的路径:
var find_path = function(groups, slug) { /* looking for a solution to this */ };
result = find_path(groups, 'pineapple');
console.log(result);
// [{ name: 'Custard Apple', slug: 'custard-apple' }, { name: 'Vanilla', slug: 'vanilla'}, { name: 'Pineapple', slug: 'pinapple' }]
// another example
result = find_path(groups, 'lemon');
console.log(result);
// [{ name: 'Lemon', slug: 'lemon' }]
我尝试了几种递归方法,在这些方法中,我试图沿函数调用保存路径,但通常结果都是重复的/通常不是期望的结果。我主要围绕递归查找和(失败的)保存路径的尝试展开讨论
那么,有没有递归的方法来解决这个问题呢?还是我的想法太复杂了 您处理的是一棵树,因此递归是一种自然的解决方案。简单的深度优先搜索(查看当前节点,然后查看其子节点)可能是最简单的解决方案。大概是这样的:
slice = (o, properties...) ->
ret = { }
ret[p] = o[p] for p in properties
ret
find_path = (a, slug) ->
for o in a
# Bail out now if this is what we're looking for.
if(o.slug == slug)
return [ slice(o, 'name', 'slug') ]
# Scan the children if not.
if(sub = find_path(o.children, slug))
return [ slice(o, 'name', 'slug') ].concat(sub)
# Explicitly return `undefined` to make sure the caller
# gets The Right Thing back.
return
演示:
递归中的每一步都不提供任何内容,也不提供从当前节点到要查找节点的路径。然后,展开递归构建通过调用的路径。诚然,这里有相当多的数组复制,但对于这样的小数据集,不值得担心(如果您有更多数据,那么您可能希望切换到某种索引结构)
slice
函数只是为了让“copye
而不是e.children
”逻辑更具可读性;不幸的是,你不能在一个数组中使用像{x.a,x.b}=obj
这样的复合结构,所以切片
函数就和你要得到的一样好(你可以说{a,b}=obj
,但是你不能添加额外的嵌套级别来得到一个对象切片)。你正在处理一个树,所以递归是一个自然的解决方案。简单的深度优先搜索(查看当前节点,然后查看其子节点)可能是最简单的解决方案。大概是这样的:
slice = (o, properties...) ->
ret = { }
ret[p] = o[p] for p in properties
ret
find_path = (a, slug) ->
for o in a
# Bail out now if this is what we're looking for.
if(o.slug == slug)
return [ slice(o, 'name', 'slug') ]
# Scan the children if not.
if(sub = find_path(o.children, slug))
return [ slice(o, 'name', 'slug') ].concat(sub)
# Explicitly return `undefined` to make sure the caller
# gets The Right Thing back.
return
演示:
递归中的每一步都不提供任何内容,也不提供从当前节点到要查找节点的路径。然后,展开递归构建通过调用的路径。诚然,这里有相当多的数组复制,但对于这样的小数据集,不值得担心(如果您有更多数据,那么您可能希望切换到某种索引结构)
slice
函数只是为了让“copye
而不是e.children
”逻辑更具可读性;不幸的是,你不能在一个应用程序中使用像{x.a,x.b}=obj
这样的复合结构,所以切片
函数就和你要得到的一样好(你可以说{a,b}=obj
,但是你不能添加额外的嵌套级别来获得对象切片)。谢谢:)回想起来,这对我来说应该更明显。谢谢:)回想起来,这对我来说应该更明显。