Как извлечь как глубоко, так и мелко вложенные поля в массиве json объектов - PullRequest
0 голосов
/ 27 февраля 2020

Допустим, у меня есть json объект:

{
    "lotOfJson": [
    {
        "value": "someName",
        "property": "name",
        "children": [],
        "constraints": {
            "IsValidName": "name someName isn't valid"
        }
    },
    {
        "value": [
            {
                "id": "firstBadId"
            },
            {
                "id": "secondBadId"
            }
        ],
        "property": "listOfIds",
        "children": [
            {
                "value": {
                    "id": "firstBadId"
                },
                "property": "0",
                "children": [
                    {
                        "value": "firstBadId",
                        "property": "id",
                        "children": [],
                        "constraints": {
                            "badIdError": "This Id is bad!"
                        }
                    }
                ]
            },
            {
                "value": {
                    "id": "secondBadId"
                },
                "property": "1",
                "children": [
                    {
                        "value": "secondBadId",
                        "property": "id",
                        "children": [],
                        "constraints": {
                            "badIdError": "This Id is bad"
                        }
                    }
                ]
            }
        ]
    }
]

}

Этот массив может иметь глубокое вложение JSON - нет способа узнать, насколько глубоко.

Всякий раз, когда есть блок, который выглядит так:

"value": "",
"property": "",
"children": [],
"constraints": {
    "": ""
}

Я хочу извлечь значения для value, property и constraints и сохранить их в массиве. Для моего "lotsOfJson" примера выше это будет выглядеть так: ["someName", "name", "name SomeName isn't valid", "firstBadId, "id", "This Id is bad!", "secondBadId, "id", "This Id is bad!"]

Так что я извлекаю значение, свойство и ограничения только тогда, когда они параллельны, как в блоке справа выше.

Я мог бы агностически извлечь все value, property и constraints, которые находятся в массиве JSON, например, с помощью итератора, но есть способ извлечь их только тогда, когда параллельная версия друг другу?

1 Ответ

1 голос
/ 27 февраля 2020

Вы можете создать рекурсивную функцию для этого, используя for...in l oop, и добавлять к результату, только если у текущего объекта нет элементов в массиве children.

const data = [{"value":"someName","property":"name","children":[],"constraints":{"IsValidName":"name someName isn't valid"}},{"value":[{"id":"firstBadId"},{"id":"secondBadId"}],"property":"listOfIds","children":[{"value":{"id":"firstBadId"},"property":"0","children":[{"value":"firstBadId","property":"id","children":[],"constraints":{"badIdError":"This Id is bad!"}}]},{"value":{"id":"secondBadId"},"property":"1","children":[{"value":"secondBadId","property":"id","children":[],"constraints":{"badIdError":"This Id is bad"}}]}]}]

function extract(data, fields) {
  let result = []

  for (let i in data) {
    if (typeof data[i] == 'object') {
      result.push(...extract(data[i], fields))
    }

    if (data.children && !data.children.length) {
      if (fields.includes(i)) {
        result = result.concat(
          typeof data[i] == 'object' ?
          Object.values(data[i]) :
          data[i]
        )
      }
    }
  }

  return result;
}

const result = extract(data, ['property', 'value', 'constraints'])
console.log(result)
...