从深度嵌套的对象(架构)创建对象路径

我有一个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中获得该对象(Schema)的所有对象路径。因此,如果有类似extractPaths(avroSchema)的内容,则上面的示例将返回:

[
   "plateNumber",
   "ownerId",
   "details.engine.size",
   "details.engine.valvesCount",
   "details.color",
   "details.rimSize",
   "isBrandNew"
]

字符串的顺序显然不重要。有人知道如何在JavaScript中实现这一点吗?


解决方案

使用递归生成器函数生成路径字符串。

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)]);

相关文章