【问题标题】:How to sort_by in descending order without reverse in jq如何在jq中按降序排序而不反转
【发布时间】:2022-10-15 16:24:40
【问题描述】:

当您有一列并希望按不同顺序对多列进行排序时 - 您将开始反向链接

我的 jq sort_by 是稳定的,但如果我需要按降序排序 - 我必须做双重反转,我不喜欢

sort_by(.person) # first sort in ascending
| reverse | sort_by(.city) | reverse # then sort by in descending

为了保持city 降序和person 升序,(但按城市) - 我觉得我需要双反转,所以这个api看起来不太好,就高级排序的性能而言。

您知道任何解决方法,而不是使用双反转吗?

【问题讨论】:

  • jq-1.6 没有指定此类排序选项的选项。如果你想要相反,你需要反转
  • 我希望有 sort/2,但是 jq: error: sort_by/2 is not defined at <top-level>
  • @Inian 1.5 有吗?所以我只需要编写自定义函数,有第二个可选参数,它会变得与jqplay不兼容?没有别的办法吧?
  • 我的意思是,截至今天,这样的选择不存在。
  • 很遗憾 jq 没有自定义排序方法。该功能至少会封装复杂性。

标签: sorting jq reverse


【解决方案1】:

与其说是一个好的解决方案,不如说是一个想法,但您可以按使用explode 获得的负代码点进行排序。至少不涉及reverse,所有标准只需要一次调用sort_by

sort_by(.person, (.city | [-explode[]]))

【讨论】:

  • 感谢您的输入,好主意,但是在一个项目中我使用查询注入,所以在某些情况下我只需要管道..我们也不确定它是字符串数字还是布尔属性,这样的查询构造函数会很难对自己。更好的方法是尝试扩展标准。现在我可以用我们使用的库的外部函数插件模拟 sort_by/2
  • @xakepp35 我完全同意提供的内置插件是可取的。让我快速补充一下,您也可以很容易地实现泛型类型区分,例如(strings | [-explode[]]), -numbers, (booleans | not) 等。也不是最好的编码风格,但仍然可行。
【解决方案2】:

此处定义的reverse_merge_sort_by(f) 是一个稳定的反向合并排序,其中主顺序由 f 确定:

# If both the input arrays $x and $y are reverse sorted according to f,
# then the result will also be reverse sorted with stability maintained
def reverse_merge_by($x; $y; f):
  def m:  # state: [i, j, array]  (i and j being indices into x and y respectively)
    .[0] as $i | .[1] as $j
    | if $i == -1 then $y[:$j + 1] + .[2]
      elif $j == -1 then $x[:$i + 1] + .[2]
      elif ($x[$i]|f) < ($y[$j]|f)  # to ensure stability, one must not use <= here
      then [$i - 1, $j,     [$x[$i]] + .[2] ] | m
      else [$i,     $j - 1, [$y[$j]] + .[2] ] | m
      end
      ;
   [($x|length - 1), ($y|length -1), []] | m;

def reverse_merge_sort_by(f):
  if length <= 1 then .
  else (length/2 |floor) as $len
  | reverse_merge_by( .[:$len] | reverse_merge_sort_by(f);
                      .[$len:] | reverse_merge_sort_by(f); f )
  end;

为方便起见,您可能需要定义一个别名,例如

def rs(f): reverse_merge_sort_by(f);

这已经通过 C 和 Go 实现(jq 和 gojq)进行了测试。

【讨论】:

    猜你喜欢
    • 2016-06-03
    • 1970-01-01
    • 2016-05-08
    • 2021-11-30
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    相关资源
    最近更新 更多