JQ按任意顺序排序键

时间:2017-10-17 18:19:33

标签: json sorting key jq

我试图按任意格式按键排序(键'事件'应该是第一个)

我知道这一个按字母顺序排序: jq -S'。' file.json

但是有一个排序键的功能,以便第一个键始终相同而不是按字母顺序排列吗?

这是为了让它们更具人性化,并且首先拥有最重要的关键

目前有: {key1:value,shouldbeFirstKey:value2,...} 想 {shouldbeFirstKey:value2,key1:value,...}

3 个答案:

答案 0 :(得分:0)

这是一个过滤器(派生自walk/1 [source]),它将使用函数对子对象的键重新排序:

def reorder(order):
    . as $in
  | if type == "object" then
      reduce (keys_unsorted|order)[] as $key(
        {}; . + { ($key):  ($in[$key] | reorder(order)) }
      )
    elif type == "array" then map( reorder(order) )
    else .
    end;

订单函数应该以任何所需的顺序返回键集。例如以下函数将“shouldbeFirstKey”移动到第一个位置

def neworder:
    "shouldbeFirstKey" as $s
  | index($s) as $i
  | if $i==null then . else [$s] + .[:$i] + .[$i+1:] end
;    

这样

  {key1:"value", shouldbeFirstKey:"value2", other:{key3:"value3", shouldbeFirstKey:"value4"}}
| reorder(neworder)

产生输出

{
  "shouldbeFirstKey": "value2",
  "key1": "value",
  "other": {
    "shouldbeFirstKey": "value4",
    "key3": "value3"
  }
}

Try it online!

答案 1 :(得分:0)

假设我们有一个带有一堆键的对象,并希望其中一些键以某种顺序出现,而其他键保持原样。然后可以使用以下示例说明的技术:

$ jq -n '{a:2,b:3,first:0,second:1} | . as $in | {first,second} + $in'

结果:

{
  "first": 0,
  "second": 1,
  "a": 2,
  "b": 3
}

让我们将定义键排序的对象称为“模板对象”(上面的{first,second})。请注意,使用上述技术,“模板对象”中的键始终显示在结果中。如果我们只希望模板对象键出现在输入中的结果中,我们可以使用以下函数修改上述方法:

def rekey(obj):
  . as $in
  | reduce (obj|keys_unsorted)[] as $k ({};
      if $in|has($k) then . + {($k): $in[$k]} else . end)
  | . + $in ;

例如:

{a:2,b:3,first:0,second:1} | rekey({first,second,third})

产生

{
  "first": 0,
  "second": 1,
  "a": 2,
  "b": 3
}

使用walk/1

如果想要递归重新排序密钥,可以使用walk/1(定义为https://github.com/stedolan/jq/blob/master/src/builtin.jq), 如此处所示,使用rekey的上述定义:

walk(if type == "object" then rekey($template) else . end)

其中$ template表示“模板对象”。

无需定义walk/1的特殊变体。只需定义一个函数,该函数将任意对象作为输入,并产生所需的重新排序。

(如果您的jq附带使用walk/1的{​​{1}}版本,则应考虑更新您的jq,或重新定义keys以使用walk/1。)< / p>

答案 2 :(得分:0)

来自@jq170727 的回答的想法:

<VictoryChart height={400} width={400}
    containerComponent={<VictoryVoronoiContainer/>}
    domainPadding={{y: 50}}
    domain={{x: [dateStart, dateEnd]}}
    >