#javascript #arrays #object #lodash #javascript-objects
Вопрос:
У меня есть схема avro, которая представляет собой глубоко вложенный объект с той же (под) структурой. Это выглядит так:
{
"type": "record",
"namespace": "company.car.v1",
"name": "CarV1",
"fields": [
{
"name": "plateNumber",
"type": "string"
},
{
"name": "ownerId",
"type": "string",
"keepThisField": "true"
},
{
"name" : "details",
"keepThisField": "true"
"type" : {
"type" : "record",
"name" : "DetailsV1",
"fields" : [
{
"name": "engine",
"type": {
"type": "record",
"name": "EngineV1",
"fields": [
{
"name": "size",
"type": "int",
"default": 0,
"keepThisField": "true"
},
{
"name": "valvesCount",
"type": "int",
"default": 0
}
]
}
},
{
"name" : "color",
"type" : "string",
"default" : "NONE"
},
{
"name" : "rimSize",
"type" : "int",
"default" : "NONE"
}
]},
"default" : {}
},
{
"name": "isBrandNew",
"type": "boolean"
}
]
}
Я хочу, чтобы в целом можно было получить все пути к объектам этого объекта (схемы) в JavaScript. Таким образом, имея что-то вроде a extractPaths(avroSchema)
, которое для приведенного выше примера вернулось бы:
[
"plateNumber",
"ownerId",
"details.engine.size",
"details.engine.valvesCount",
"details.color",
"details.rimSize",
"isBrandNew"
]
Очевидно, что порядок строк не имеет значения. У кого-нибудь есть идеи, как этого можно достичь в JavaScript?
Ответ №1:
Используйте рекурсивную функцию генератора для создания строки пути.
var schema = { "type": "record", "namespace": "company.car.v1", "name": "CarV1", "fields": [{ "name": "plateNumber", "type": "string" }, { "name": "ownerId", "type": "string", "keepThisField": "true" }, { "name": "details", "keepThisField": "true", "type": { "type": "record", "name": "DetailsV1", "fields": [{ "name": "engine", "type": { "type": "record", "name": "EngineV1", "fields": [{ "name": "size", "type": "int", "default": 0, "keepThisField": "true" }, { "name": "valvesCount", "type": "int", "default": 0 }] } }, { "name": "color", "type": "string", "default": "NONE" }, { "name": "rimSize", "type": "int", "default": "NONE" }] }, "default": {} }, { "name": "isBrandNew", "type": "boolean" }] }
function* extractPaths(schema, value) {
for (const { name, type } of schema.fields) {
let path = value ? `${value}.${name}` : name
if (typeof type == "object")
yield* extractPaths(type, path);
else
yield path
}
}
console.log([...extractPaths(schema)]);