首页 > 解决方案 > 将数组与jq中的其他数组一起排序

问题描述

我在一个结构中有两个数组,但数组元素之间有逻辑连接。(例如,comments[1]属于records[1]comments[2]属于records[2]

这些数组按记录数组的字母顺序排序。当我想为两个数组添加一个新元素时,我对两个数组都进行了排序。对于记录数组很容易,但是注释数组的元素必须以与记录的每个元素相同的方式移动。

输入:

{
  "records":
    [
     {"content":"a"},
     {"content":"z"}
    ], 
     "comments":[
         {"content":"something"},
         {"content":"anything"}
     ]
}

新元素被添加到数组的末尾:

{ 
  "records":[
      {"content":"a"},
      {"content":"z"},
      {"content":"b"}
  ],
  "comments":[
      {"content":"something"},
      {"content":"anything"},
      {"content":"new element"}
  ]
}

Expected sorted output:

```json
{
  "records":[
     {"content":"a"},
     {"content":"b"},
     {"content":"z"}
  ],
  "comments":[
     {"content":"something"},
     {"content":"new element"},
     {"content":"anything"}
  ]
}

我尝试了"to_elements,map和没有任何(部分)结果的函数transposeadd

标签: arraysjsonsortingjq

解决方案


bsearch您可以使用查找插入点,然后使用它来执行两次插入,而不是将新元素附加到数组中。具体来说,如果 $x 不在排序数组中,则 $x 在数组中的插入点是-1 - bsearch($x)

您可能会发现此辅助函数很有用:

def insert($x;$i): .[:$i]+[$x]+.[$i:];

解决方案

这是手头问题的解决方案:

# It is assumed that (.|f) is a sorted array
def insert_into_sorted($x; f; $y; g):
  def insert($x;$i): .[:$i]+[$x]+.[$i:];
  (f|bsearch($x)) as $ix
  | (if $ix > -1 then $ix else -1 - $ix end) as $i
  | f|=insert($x; $i)
  | g|=insert($y; $i) ;

insert_into_sorted( {"content": "b"}; .records; 
                    {"content": "new element"}; .comments)


推荐阅读