在对象数组中找到具有特定键的对象的路径
Find the path of an object in which there is a key with a speicific in a array of objects
假设我有如下字典数组。如何使用 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"
您可以定义一个递归函数 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
sub-array 的方式中的一个小错误。
应用以下更改应该会导致您看到的错误:
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
您可以找到该路径,如果找到,则将该节点的对象放入结果集中。
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; }
我终于找到了一种方法,这是我的算法步骤:
首先,DFS (Depth First Search) 您的树,直到您找到具有您正在寻找的 id
的节点
找到后推到breadscrumpArray
和return breadscrumpArray
每次搜索 submenu
元素时,我们都会知道我们要查找的节点是否是该元素的子节点,就好像它不是子节点一样,[=函数 getBreadcrumbs
的 36=] 将是 false
希望对你有所帮助,有什么问题可以在评论里告诉我,干杯!
function getBreadcrumbs(menuItems, id, breadcrumpsArray) {
for (var i = 0; i < menuItems.length; i++) {
if (menuItems[i].id == id) {
// Found the node, push it and return the breadcrumpsArray
breadcrumpsArray.push({
id: menuItems[i].id,
name: menuItems[i].name
});
return breadcrumpsArray;
} else {
if (typeof menuItems[i].submenus !== 'undefined') {
if (menuItems[i].submenus.length > 0) {
if (getBreadcrumbs(menuItems[i].submenus, id, breadcrumpsArray)) {
// Unshift to push the node to the front of the array
breadcrumpsArray.unshift({
id: menuItems[i].id,
name: menuItems[i].name
});
return breadcrumpsArray;
}
}
} else {
// The node we are looking for is not in this path of the tree
return false;
}
}
}
}
假设我有如下字典数组。如何使用 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"
您可以定义一个递归函数 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
sub-array 的方式中的一个小错误。
应用以下更改应该会导致您看到的错误:
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
您可以找到该路径,如果找到,则将该节点的对象放入结果集中。
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; }
我终于找到了一种方法,这是我的算法步骤:
首先,DFS (Depth First Search) 您的树,直到您找到具有您正在寻找的
id
的节点找到后推到
breadscrumpArray
和returnbreadscrumpArray
每次搜索
submenu
元素时,我们都会知道我们要查找的节点是否是该元素的子节点,就好像它不是子节点一样,[=函数getBreadcrumbs
的 36=] 将是false
希望对你有所帮助,有什么问题可以在评论里告诉我,干杯!
function getBreadcrumbs(menuItems, id, breadcrumpsArray) {
for (var i = 0; i < menuItems.length; i++) {
if (menuItems[i].id == id) {
// Found the node, push it and return the breadcrumpsArray
breadcrumpsArray.push({
id: menuItems[i].id,
name: menuItems[i].name
});
return breadcrumpsArray;
} else {
if (typeof menuItems[i].submenus !== 'undefined') {
if (menuItems[i].submenus.length > 0) {
if (getBreadcrumbs(menuItems[i].submenus, id, breadcrumpsArray)) {
// Unshift to push the node to the front of the array
breadcrumpsArray.unshift({
id: menuItems[i].id,
name: menuItems[i].name
});
return breadcrumpsArray;
}
}
} else {
// The node we are looking for is not in this path of the tree
return false;
}
}
}
}