jq中一系列对象的地图语义

semantics of map on a sequence of objects in jq

假设我有一个文件 fruit.json 包含以下行:

[
  {
    "name": "apple",
    "color": "red",
    "price": 20
  },
  {
    "name": "banana",
    "color": "yellow",
    "price": 15
  },
  {
    "name": "pineapple",
    "color": "orange",
    "price": 53
  }
]

如果我这样做 jq '. | map(.)' fruit.json 那么我得到原始数据。这是预期的。第二个.指的是整个数组中的一个元素。

但是如果我这样做 jq '.[] | map(.)' fruit.json 然后我得到这个:

[
  "apple",
  "red",
  20
]
[
  "banana",
  "yellow",
  15
]
[
  "pineapple",
  "orange",
  53
]

有人可以解释一下这是怎么回事吗?具体来说,

  1. . 之后的 [] 从输入数组中去除括号。做 我们有 [] 运算符的名称吗?该手册似乎将其视为 没有定义的非常基本的东西。
  2. 我们是否通过将 [] 附加到 . 来为生成的事物命名? 显然它不是一个对象。如果我们这样做 jq '.[]' fruit.json 我们可以看到它看起来非常类似于数组。 但显然它的行为完全不同。
  3. 为什么map函数好像走两步 里面的水平而不是一个?这是 如果我们这样做会更明显 jq '.[] | map(. | length)' fruit.json 并看到 map 中的 . 函数引用输入数组的(对象)元素的值部分。

提前谢谢大家!

.[] 生成给定的数组或对象的值。

例如,

[ "a", "b", "c" ] | .[]

等同于

[ "a", "b", "c" ] | .[0], .[1], .[2]

并生成三个字符串:abc.


map( ... )

等同于

[ .[] | ... ]

这意味着

map( . )    ≡    [ .[] | . ]    ≡    [ .[] ]

对于数组,这意味着

map( . )    ≡    [ .[0], .[1], ... ]    ≡    .

对于一个对象,这意味着

map( . )    ≡    [ .["key1"], .["key2"], ... ]

The [] after . strips away the brackets from the input array.

没有括号。 jq 程序不处理 JSON 文本,而是它所代表的数据结构。

当给定数组或对象时,.[] 生成该数组或对象的元素值。

Do we have a name for the [] operator?

文档称它为 Array/Object 值迭代器,但它实际上只是索引运算符的特定用法。

Array/Object 值迭代器 在文档中归因于 .[],但这并不准确。它前面不一定是 .,但前面必须有一个表达式。这将它与数组构造运算符区分开来。

用技术术语来说,

  • []作为环号运算符([ EXPR ])是数组构造运算符,而
  • []作为后缀运算符(EXPR [ EXPR? ])是索引运算符,当括号中没有任何内容时,它被称为array/object值迭代器。

Do we have a name for the resulting thing by appending [] to .? Obviously it's not an object. If we do jq '.[]' fruit.json we can see that it looks very similar to an array. But apparently it behaves quite differently.

我们称之为流。

我不确定如何调用流的组件。我通常使用“值”。

例如,

"a", "b", "c"       // Produces a stream of three values.
"abc" / "" | .[]    // Same

当序列化为每行一个值的文件时(就像您使用 -c 一样),它被称为 "JSON lines",建议的命名约定为 .jsonl.

Why is it the case that the map function seems to go two levels inside instead of one? This is more obvious if we do jq '.[] | map(. | length)' fruit.json and see that the . inside the map function refers to the value part of an (object) element of the input array.

没有,只有一个。

在那个例子中,

  • .[] 遍历数组的值。
  • map 遍历对象的值。