比方说,我有如下的字典数组。如何使用id: 121
查找到对象的路径。我正在尝试用javascript做到这一点,但与此无关。我需要一种算法或某种方法来实现这一目标。
我期望的结果类似于[{id:1, name:"foo"}, {id: 12, name:"shoo"}, {id: 121, name:"jhj"}]
[
{
"id": 1,
"name": "foo",
"submenus": [
{
"id": 11,
"name": "bar",
"submenus": [
{
"id": 111,
"name": "abc"
}
]
},
{
"id": 12,
"name": "shoo",
"submenus": [
{
"id": 121,
"name": "jhj"
}
]
}
]
},
{
"id": 2,
"name": "kjk"
}
]
这是我为此编写的代码。该代码用于VueJS。
getBreadcrumbs(menuItems, id, breadcrumpsArray) {
for (var i = 0; i < menuItems.length; i++) {
if (menuItems[i].id == id) {
breadcrumpsArray.push({
id: menuItems[i].id,
name: menuItems[i].text
})
return breadcrumpsArray
} else {
if (menuItems[i].submenus !== 'undefined') {
if (menuItems[i].submenus.length > 0) {
console.log('shoo')
this.getBreadcrumbs(menuItems[i].submenus, id, breadcrumpsArray)
}
}
}
}
}
这显示错误信息:
Error in render: "TypeError: menuItems[i].submenus is undefined"
答案 0 :(得分:2)
您可以定义一个递归函数findPath()
来实现所需的功能。请参阅下面的片段中记录的注释:
const data=[{"id":1,"name":"foo","submenus":[{"id":11,"name":"bar","submenus":[{"id":111,"name":"abc"}]},{"id":12,"name":"shoo","submenus":[{"id":121,"name":"jhj"}]}]},{"id":2,"name":"kjk"}];
/* Define a recursive function that finds the item path from root
of the data set, to the first child found with matching id */
const findPath = (items, id) => {
/* Iterate the items of this level */
for(const item of items) {
if(item.id === id) {
/* If id matches id, return tail of resulting array that
will be our path result */
return [item]
}
else if(Array.isArray(item.submenus)) {
/* If submenus sub array present, search the items of the
submenu recursivly for a nested child with matching id */
const result = findPath(item.submenus, id)
if(Array.isArray(result)) {
/* If recursive call returns an array result, this means
a nested child with id was found, so prefix this item to
the results array */
return [item].concat(result)
}
}
}
}
/* Map id and name of each item in found path to result array */
const result = findPath(data, 121).map(({ id, name }) => ({ id, name }));
console.log( result );
另外,作为单独的注释,在您当前的代码中,这是检查菜单项上submenus
子数组是否存在的一个小错误。
应用以下更改应导致您看到的错误:
getBreadcrumbs(menuItems, id, breadcrumpsArray) {
for (var i = 0; i < menuItems.length; i++) {
if (menuItems[i].id == id) {
breadcrumpsArray.push({
id: menuItems[i].id,
name: menuItems[i].text
});
} else {
/* Add "typeof" here to determine if submenus if undefined in this way */
if (typeof menuItems[i].submenus !== 'undefined') {
if (menuItems[i].submenus.length > 0) {
this.getBreadcrumbs(menuItems[i].submenus, id, breadcrumpsArray)
}
}
}
}
/* Move this here */
return breadcrumpsArray;
}
有关此typeof
运算符see this documentation
答案 1 :(得分:1)
您可以找到路径,如果找到该路径,则将节点的对象带入结果集中。
function findPath(array, target) {
var path;
return array.some(({ id, name, submenus = [] }) => {
if (id === target) return path = [{ id, name }];
var temp = findPath(submenus, target);
if (temp.length) return path = [{ id, name }, ...temp];
})
? path
: [];
}
var array = [{ id: 1, name: "foo", submenus: [{ id: 11, name: "bar", submenus: [{ id: 111, name: "abc" }] }, { id: 12, name: "shoo", submenus: [{ id: 121, name: "jhj" }] }] }, { id: 2, name: "kjk" }];;
console.log(findPath(array, 121))
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:1)
我终于找到了一种方法,这是我算法的步骤:
首先,DFS (Depth First Search)您的树,直到找到您要查找的id
的节点
找到它后,将其推到breadscrumpArray
并返回breadscrumpArray
每次我们搜索submenu
元素时,我们都会知道我们要查找的节点是否是该元素的子元素,就像它不是子元素一样,函数{{ 1}}将是getBreadcrumbs
希望能有所帮助,如果您有任何疑问,请告诉我,加油!
false