Поиск в глубоком файле JSON

#javascript #node.js #json

#javascript #node.js #json

Вопрос:

Я хотел бы найти объект JSON, выполнив поиск специального ключа изнутри. Например, в следующем случае:

 {
  "1": {
    "name": "usa",
    "position": 8,
    "code": 1,
    "other": false,
    "new": false,
    "enabled": true,
    "services": {
      "service_vkcom": {
        "count": 6039,
        "popular": false,
        "code": 1,
        "id": 1,
        "service": "Вконтакте",
        "slug": "vkcom"
      },
      "service_3223": {
        "count": 4053,
        "popular": false,
        "code": 1,
        "id": 2,
        "service": "Facebook",
        "slug": 3223
      }
}
  

Просматривая слово «usa», я бы хотел, чтобы мне вернулось все значение «1».

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

1. Насколько глубоко могло быть спрятано слово? Только первый уровень? Что вы пробовали? Какой-нибудь код для показа?

2. И знаете ли вы, в каких полях вы хотите выполнить поиск … или в любом другом поле? Ваши критерии немного расплывчаты

3. Поскольку мой JSON не находится в массиве, я не могу выполнить какой-либо фильтр, некоторые и т.д… Действительно, мое имя не может быть ниже, чем в моем примере выше.

4. @charlietfl Я хочу выполнить поиск только по имени и вернуть весь объект, связанный с именем (в моем примере это 1)

5. Спасибо @LawrenceCherone, но, как упоминал Евгений Сунич, это не будет работать для глубоких объектов

Ответ №1:

Вы можете выполнить поиск recursively по значению и вернуть объект, в котором оно находится:

 let obj = {
  "1": {
    "name": "usa",
    "position": 8,
    "code": 1,
    "other": false,
    "new": false,
    "enabled": true,
    "services": {
      "service_vkcom": {
        "count": 6039,
        "popular": false,
        "code": 1,
        "id": 1,
        "service": "Вконтакте",
        "slug": "vkcom"
      },
      "service_3223": {
        "count": 4053,
        "popular": false,
        "code": 1,
        "id": 2,
        "service": "Facebook",
        "slug": 3223
      }
    }
  }
};

function getParent(obj, val) {
    let res = []; 
    for(let p in obj)
        if (typeof(obj[p]) == 'object')
            res = res.concat(getParent(obj[p], val));
        else if (obj[p] == val) 
            res.push(obj);
    return res;
}

console.log(getParent(obj, "usa"));
console.log(getParent(obj, 6039));
console.log(getParent(obj, "Facebook"));  

Ответ №2:

Вот ответ, который использует object-scan

 // const objectScan = require('object-scan');

const data = {"1":{"name":"usa","position":8,"code":1,"other":false,"new":false,"enabled":true,"services":{"service_vkcom":{"count":6039,"popular":false,"code":1,"id":1,"service":"Вконтакте","slug":"vkcom"},"service_3223":{"count":4053,"popular":false,"code":1,"id":2,"service":"Facebook","slug":3223}}}};

const find = (obj, name) => objectScan(['**.name'], {
  abort: true,
  rtn: 'parent',
  filterFn: ({ value }) => value === name
})(obj);

console.log(find(data, 'usa'));
// => { name: 'usa', position: 8, code: 1, other: false, new: false, enabled: true, services: { service_vkcom: { count: 6039, popular: false, code: 1, id: 1, service: 'Вконтакте', slug: 'vkcom' }, service_3223: { count: 4053, popular: false, code: 1, id: 2, service: 'Facebook', slug: 3223 } } }  
 .as-console-wrapper {max-height: 100% !important; top: 0}  
 <script src="https://bundle.run/object-scan@13.7.1"></script>  

Отказ от ответственности: Я автор object-scan