Получить путь к объекту JSON по ключу?

#javascript #arrays #json #lodash

#javascript #массивы #json #Lodash

Вопрос:

Учитывая следующий объект:

 const ourObject = {
    "payload": {
        "streams": [
            {
                "children": {
                    "2165d20a-6276-468f-a02f-1abd65cad618": {
                        "additionalInformation": {
                            "narrative": {
                                "apple": "A",
                                "banana": "B"
                            },
                            "myInventory": {
                                "fruits": [
                                    {
                                        "name": "apple"
                                    },
                                    {
                                        "name": "banana"
                                    }
                                ]
                            }
                        }
                    }
                }
            }
        ]
    }
};
 

Мы пытаемся найти путь myInventory , проблема в том, что дочерний uuid будет отличаться каждый раз. Есть идеи, как мы можем получить путь myInventory , указав его в качестве ключа, и получить путь к нему в формате json?

Комментарии:

1. streams это массив, всегда ли в нем будет один элемент? И children внутри него будет только один ключ?

Ответ №1:

Если все динамично, может помочь программный поиск по ключу

 const ourObject = {
    "payload": {
        "streams": [
            {
                "children": {
                    "2165d20a-6276-468f-a02f-1abd65cad618": {
                        "additionalInformation": {
                            "narrative": {
                                "apple": "A",
                                "banana": "B"
                            },
                            "myInventory": {
                                "fruits": [
                                    {
                                        "name": "apple"
                                    },
                                    {
                                        "name": "banana"
                                    }
                                ]
                            }
                        }
                    }
                }
            }
        ]
    }
};

const getPath = (key, o) => {
  if (!o || typeof o !== "object") {
    return "";
  }

  const keys = Object.keys(o);
  for(let i = 0; i < keys.length; i  ) {
    if (keys[i] === key ) {
      return key;
    }
    
    const path = getPath(key, o[keys[i]]);
    if (path) {
      return keys[i]   "."   path;
    }
  }
  return "";
};

const getValueForKey = (key, o) => {
  if (!o || typeof o !== "object") {
    return undefined;
  }

  const keys = Object.keys(o);
  for(let i = 0; i < keys.length; i  ) {
    if (keys[i] === key ) {
      return o[key];
    }
    
    const value = getValueForKey(key, o[keys[i]]);
    if (value) {
      return value;
    }
  }
  return undefined;
}

console.log(getPath("myInventory", ourObject))
console.log(getValueForKey("myInventory", ourObject)) 

Ответ №2:

Не уверен, правильно ли я понимаю вопрос, но

 let uuid = '2165d20a-6276-468f-a02f-1abd65cad618';
ourObject.payload.streams[0].children[uuid].additionalInformation.myInventory
 

Комментарии:

1. Дело в том, что uuid не будет известен каждый раз, так как же мы можем получить доступ к myInventory на основе только ключа. Например, использование подстановочного знака не будет работать: ourObject.payload.streams[0].children[*].additionalInformation.myInventory

Ответ №3:

 var changingKey = Object.keys(ourObject["payload"]["streams"][0]["children"])[0]; 

console.log(ourObject["payload"]["streams"][0]["children"][changingKey]["additionalInformation"]["myInventory"]);
 

Ответ №4:

Хорошо, вы могли бы создать вспомогательную функцию, которая получает UUID. Поскольку это объект, поиск близок к O (1), особенно учитывая случай, когда дочерние элементы имеют здесь только одну пару ключ-значение.

 function getUUIDFromPayload(payload) {
    let obj = payload.streams[0].children
    let uuid = Object.keys(obj)[0]
    return uuid
}
 

Использование

 const uuid = getUUIDFromPayload(payload)
ourObject.payload.streams[0].children[uuid].additionalInformation.myInventory