使用jq获取特定键的所有父键

5
我想要做的是在我的json中“遍历”,并为每个名为“base”的键添加一个键,该键是此键的完整“路径”。 这是我的JSON:
{
  "entity": {
    "product": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": ["product", "products", "pdt", "pdts"]
      }
    },
    "rabbit": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": ["rabbit", "rabbits"]
      }
    }
  }
}

And I want a result like this :

{
  "entity": {
    "product": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": ["product", "products", "pdt", "pdts"],
        "path": "entity.product.title"
      }
    },
    "rabbit": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": ["rabbit", "rabbits"]
        "path": "entity.rabbit.title"
      }
    }
  }
}

实际上,我已经实现了这个功能,但我只得到了一个子密钥:
walk(if type == "object" and .base then  keys[] as $k | .base |= {path: $k} else . end)

结果:

{
  "entity": {
    "product": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": {
          "path": "base"
        }
      }
    },
    "rabbit": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": {
          "path": "base"
        }
      }
    }
  }
}

我也尝试了这个:

walk(if type == "object" and .base then  paths(..) as $v | .base |= {path: $v} else . end)

结果:

{
  "entity": {
    "product": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": {
          "path": [
            "base",
            3
          ]
        }
      }
    },
    "rabbit": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": {
          "path": [
            "base",
            1
          ]
        }
      }
    }
  }
}

非常感谢您的建议和专业知识!

3个回答

2
这里有一种方法:
reduce paths(objects | has("base")) as $p (.;
  setpath($p + ["path"]; $p | join("."))
)

在线演示


1

这是一次关于pathpathssetpathobjects的真实学习经历。在阅读其他答案之前,我显然重新实现了setpath

def add_path(p; val):
    if p|length == 0
    then .path = val
    else .[p[0]] |= add_path(p[1:]; val)
    end;

reduce ([paths(..) | select(last == "base")] | unique | map(.[:-1]))[] as $path (.;
    add_path($path; ($path | join(".")))
)

1
您可以使用path获得路径的数组表示,使用join(假设字段名称类似于simple, identifier-like),并使用setpath进行设置:
jq '
  reduce path((.. | objects | select(.base))) as $p (.;
    setpath($p + ["path"]; $p | join("."))
  )
'

{
  "entity": {
    "product": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": [
          "product",
          "products",
          "pdt",
          "pdts"
        ],
        "path": "entity.product.title"
      }
    },
    "rabbit": {
      "att": {
        "number_of_values": "Number of values"
      },
      "title": {
        "base": [
          "rabbit",
          "rabbits"
        ],
        "path": "entity.rabbit.title"
      }
    }
  }
}

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接