我有一个深层嵌套的JavaScript对象,并且知道一个值位于该对象的最低位置。我想知道父键和祖父母键。
我设置了一个jsbin https://jsbin.com/yimugezuxe/edit?js,console
基于值“ uniqueID#9aserdf”,我想知道/返回其父键:下一个对象的“阶段2”和“级别2”:
const obj = {
"Level 1": {
"Stage 1": [
{
"title": "Parent 1",
"id": "Parent1#id",
"Children": [
{
"title": "Steve",
"id": "uniqueID1"
},
{
"title": "James",
"id": "uniqueID#9"
}
]
}
]
},
"Level 2": {
"Stage 1": [
{
"title": "Parent 4",
"id": "Parent4#id",
"Children": [
{
"title": "Tim",
"id": "uniqueIDadsf"
},
{
"title": "Hans",
"id": "uniqueID#9asdf"
}
]
}
],
"Stage 2": [
{
"title": "Parent 10",
"id": "Parent10#id",
"Children": [
{
"title": "Chris",
"id": "uniqueIDadsf33"
},
{
"title": "Jack",
"id": "uniqueID#9aserdf"
}
]
}
]
}
};
// based on the value 'uniqueID#9aserdf' I want to know/return its parent keys: 'Stage 2' and 'Level 2'
答案 0 :(得分:2)
类似这样的东西:
for (var prop in obj) {
for (var prop2 in obj[prop]) {
}
}
然后使用此方法向下迭代并检查
这是一个完整的例子:
for (var prop in obj) {
for (var prop2 in obj[prop]) {
//console.log(prop2);
for (var prop3 in obj[prop][prop2]) {
//console.log("->"+prop3);
for (var prop4 in obj[prop][prop2][prop3]) {
//console.log("->"+"->"+prop4);
for (var prop5 in obj[prop][prop2][prop3][prop4]) {
//console.log("->"+"->"+"->"+prop5);
for (var prop6 in obj[prop][prop2][prop3][prop4][prop5]) {
//console.log("->"+"->"+"->"+"->"+prop6);
if (obj[prop][prop2][prop3][prop4][prop5][prop6] == "uniqueID#9aserdf") {
console.log("Stage :" +prop2 + " == Level :" + prop);
}
}
}
}
}
}
}
您可以删除代码中的注释,以帮助查看您在对象中的位置。
答案 1 :(得分:2)
尝试以下代码:
它使用递归并提供父节点。
const obj = {
"Level 1": {
"Stage 1": [{
"title": "Parent 1",
"id": "Parent1#id",
"Children": [{
"title": "Steve",
"id": "uniqueID1"
},
{
"title": "James",
"id": "uniqueID#9"
}
]
}]
},
"Level 2": {
"Stage 1": [{
"title": "Parent 4",
"id": "Parent4#id",
"Children": [{
"title": "Tim",
"id": "uniqueIDadsf"
},
{
"title": "Hans",
"id": "uniqueID#9asdf"
}
]
}],
"Stage 2": [{
"title": "Parent 10",
"id": "Parent10#id",
"Children": [{
"title": "Chris",
"id": "uniqueIDadsf33"
},
{
"title": "Jack",
"id": "uniqueID#9aserdf"
}
]
}]
}
};
let path = [];
function getParentAndGrandParent(path, json, value) {
for (var key in json) {
if (typeof json[key] === 'object') {
path.push(key.toString());
// console.log("PAth : " + path)
getParentAndGrandParent(path, json[key], value);
path.pop();
} else {
if (json[key] == value) {
console.log("Parent : " + path);
}
}
}
}
getParentAndGrandParent(path, obj, 'uniqueID#9asdf')
答案 2 :(得分:1)
这是一个返回带有Level和Stage的元组的函数,如果没有匹配的ChildrenId,则返回[null,null]。
这有点混乱,但是我还没有找到一种简单的方法。
const findAncestors = (obj, ChildrenId) => {
let stageResult = null;
const result = Object.entries(obj).find(level => {
const validLevel = Object.values(level[1]).find((stage, index) => {
const validId = stage[0].Children.some(children => {
return children.id === ChildrenId
})
if (validId) {
stageResult = Object.keys(level[1])[index];
}
return validId;
})
return validLevel != undefined;
})
return stageResult === null ? [null, null] : [result[0], stageResult];
}
答案 3 :(得分:0)
我将this answer的getObject
由Zach修改为Find by key deep in a nested object,以接受属性名称和值。
我将this answer的findPath
从ibrahim mahrir直接拉到Javascript - Find path to object reference in nested object。
将它们组合在一起,可以获取包含要查找的属性的对象,然后使用该对象获取该对象的路径。您可以更改findPath
以返回字符串数组,如果需要的话,可以仅拉前两个字符串。
function getObject(theObject, propName, propValue) {
var result = null;
if(theObject instanceof Array) {
for(var i = 0; i < theObject.length; i++) {
result = getObject(theObject[i], propName, propValue);
if (result) {
break;
}
}
}
else
{
for(var prop in theObject) {
//console.log(prop + ': ' + theObject[prop]);
if(prop == propName) {
if(theObject[prop] == propValue) {
return theObject;
}
}
if(theObject[prop] instanceof Object || theObject[prop] instanceof Array) {
result = getObject(theObject[prop], propName, propValue);
if (result) {
break;
}
}
}
}
return result;
}
function findPath(a, obj) {
for(var key in obj) { // for each key in the object obj
if(obj.hasOwnProperty(key)) { // if it's an owned key
if(a === obj[key]) return key; // if the item beign searched is at this key then return this key as the path
else if(obj[key] && typeof obj[key] === "object") { // otherwise if the item at this key is also an object
var path = findPath(a, obj[key]); // search for the item a in that object
if(path) return key + "." + path; // if found then the path is this key followed by the result of the search
}
}
}
}
const data = {
"Level 1": {
"Stage 1": [
{
"title": "Parent 1",
"id": "Parent1#id",
"Children": [
{
"title": "Steve",
"id": "uniqueID1"
},
{
"title": "James",
"id": "uniqueID#9"
}
]
}
]
},
"Level 2": {
"Stage 1": [
{
"title": "Parent 4",
"id": "Parent4#id",
"Children": [
{
"title": "Tim",
"id": "uniqueIDadsf"
},
{
"title": "Hans",
"id": "uniqueID#9asdf"
}
]
}
],
"Stage 2": [
{
"title": "Parent 10",
"id": "Parent10#id",
"Children": [
{
"title": "Chris",
"id": "uniqueIDadsf33"
},
{
"title": "Jack",
"id": "uniqueID#9aserdf"
}
]
}
]
}
};
const o = getObject(data, "id", "uniqueID#9aserdf");
console.log(o);
const path = findPath(o, data);
console.log(path);