Проверка элементов одного объекта с помощью другого


К сожалению, возникла трудность для которой я не могу найти решение. Помогите пожалуйста.

Есть объект (может быть совершенно разным, это просто пример):

payload = {
    "obj1": "text1",
    "obj2": 123,
    "obj3": "ok",
    "arr1": ["a", "b"],
    "obj4": {
      "result": "ok",
      "description": "desc....4-2"
    },
    "obj5": {
        "obj51": {
            "result": "ok",
            "description": "desc....5-1"
        }
    },
    "arr2": [1, 2]
};

Конечная цель: Нужно проверить, есть ли в payload по определенному пути, определенный ключ с определенным значением.
Например, есть ли по пути "payload.obj5.obj51" ключ "result" со значением "ok".

Для этого решил создать отдельный объект с требованиями для поиска:

searchOptions = {
    "key": "result", //Т.е. нужно найти ключ "result"
    "path": "obj5.obj51.result", //По пути "obj5.obj51.result" в payload
    "value": "ok" //И значение его должно быть "ok"
}

Дальше начинаются проблемы. Проработал 3 основных, как мне казалось рациональных направления:

  1. Преобразование payload в json string и поиск нужного через регулярные выражение - получилось очень громоздкое и неработающее выражение.
  2. Преобразование объекта в массив с помощью Object.entries() - если в объекте глубокая вложенность элементов, нужна рекурсия для получения всех элементов и это привело меня к следующему пункту.
  3. Раскрытие всех элементов рекурсией и попытка сравнить параметры - рекурсия работает только до первого найденного value.
Object.prototype.getKeyByValue = function(value, objs) {
  for (var prop in this) {
    if (this.hasOwnProperty(prop)) {
      if (this[prop] === value) {
        return prop;
      } else if (typeof this[prop] === "object" && objs.indexOf(this[prop]) == -1) {
        objs.push(this[prop]);
        var res = this[prop].getKeyByValue(value, objs);
        if (res)
          return prop + "." + res;
      }
    }
  }
}

К сожалению, рациональных вариантов решения этой задачи я не знаю (и не нашел).

Возможно Вы знаете рациональный способ решения этой задачи?


Ответы (1 шт):

Автор решения: Aziz Umarov

Я что-то не пойму откуда такая сложность.

Вам нужно

var object = {....}

проверить по какому-то пути

if (isKeyValue(object, 'obj5.obj51.result', 'ok')) {
....
} else {
.... // нет такого 
}

isKeyValue(object, 'obj5.obj51.result', 'ok') - по вашей логике - это тоже самое что и

isKeyValue(object['obj5'], 'obj51.result', 'ok') - или

isKeyValue(object['obj5']['obj51'], 'result', 'ok') - посмотреть и сделать итерацию.

function isKeyValue(object, key, value) {
 let keys =  key.split(".");
 let firstKey = keys.shift();
 if (firstKey != null && keys.length > 0 && object[firstKey] != null) { 
   return isKeyValue(object[firstKey], keys.join("."), value);
 } else {
   return object[firstKey] === value ? `${value} найден`: `нет такого`;
 }
}

подумайте над решением такого вида.

→ Ссылка