json - "Transpose"/"Rotate"/"Flip"JSON 元素

标签 json jq transpose

我想“转置”(不确定这个词是否正确)JSON 元素。

例如,我有一个这样的 JSON 文件:

{
  "name": {
    "0": "fred",
    "1": "barney"
  },
  "loudness": {
    "0": "extreme",
    "1": "not so loud"
  }
}

...我想生成一个像这样的 JSON 数组:

[
  {
    "name": "fred",
    "loudness": "extreme"
  },
  {
    "name": "barney",
    "loudness": "not so loud"
  }
]

我的原始 JSON 具有比“名称”和“响度”更多的第一级元素,以及更多的名称、特征等。

对于这个简单的示例,我可以像这样完全指定转换:

$ echo '{"name":{"0":"fred","1":"barney"},"loudness":{"0":"extreme","1":"not so loud"}}'| \
> jq '[{"name":.name."0", "loudness":.loudness."0"},{"name":.name."1", "loudness":.loudness."1"}]'

[
  {
    "name": "fred",
    "loudness": "extreme"
  },
  {
    "name": "barney",
    "loudness": "not so loud"
  }
]

...但这对于原始 JSON 是不可行的。

对于更大的 JSON 文件,jq 如何在与 key 无关的情况下创建所需的输出?

最佳答案

是的,transpose 是一个合适的词,如下所示。

下面的通用帮助函数提供了一个简单的解决方案,它完全不知道键名,包括封闭对象和内部对象:

# Input: an array of values
def objectify($keys):
  . as $in | reduce range(0;length) as $i ({}; .[$keys[$i]] = $in[$i]);

假设内键顺序的一致性

假设内部对象中的键名以一致的顺序给出,现在可以得到如下解决方案:

keys_unsorted as $keys
| [.[] | [.[]]] | transpose
| map(objectify($keys))

不假设内键顺序的一致性

如果不能假定内部键的顺序是一致的,那么一种方法是对它们进行排序,例如使用这个通用辅助函数:

def reorder($keys):
  . as $in | reduce $keys[] as $k ({}; .[$k] = $in[$k]);

或者如果你更喜欢 reduce-free def:

def reorder($keys): [$keys[] as $k | {($k): .[$k]}] | add;

上面的“主”程序可以修改如下:

keys_unsorted as $keys
| (.[$keys[0]]|keys_unsorted) as $inner
| map_values(reorder($inner))
| [.[] | [.[]]] | transpose
| map(objectify($keys))
警告

上述解决方案仅考虑第一个内部对象中的键名。

关于json - "Transpose"/"Rotate"/"Flip"JSON 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64455986/

相关文章:

java - Servlet 中 JSON 的解析器就像 XML 的 SAX 一样

javascript - JSON.parse exptected ',' 或 '}' 有什么想法吗?两者都不工作

jq - 文本拆分为多行时出现解析错误

python - 根据许多变量转置 Python Dataframe

python - Pandas 在行上设置多索引,然后转置到列

c# - 反序列化 JSON 时出错

java - 如何在java中使用非字符串键名创建JSON数组?

json - 从 bash 中的目录获取文件并使用 jq 构建 JSON 对象

json - cbimport 不导入从 cbq 命令中提取的文件

arrays - 转置一个不代表正方形的一维数组