如何使用jq获取两个JSON数组的交集 [英] how to get the intersection of two JSON arrays using jq

查看:304
本文介绍了如何使用jq获取两个JSON数组的交集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定数组X和Y(最好同时作为输入,但是以一个作为输入,另一个作为硬编码),我如何使用jq输出包含两者共同的所有元素的数组?例如这样的f的值是什么

Given arrays X and Y (preferably both as inputs, but otherwise, with one as input and the other hardcoded), how can I use jq to output the array containing all elements common to both? e.g. what is a value of f such that

echo '[1,2,3,4]' | jq 'f([2,4,6,8,10])'

将输出

[2,4]

?

我尝试了以下操作:

map(select(in([2,4,6,8,10])))  --> outputs [1,2,3,4]
select(map(in([2,4,6,8,10])))  --> outputs [1,2,3,4,5]

推荐答案

一个简单且相当快速(但有些天真)的过滤器实际上可以完成您想要的操作,可以定义如下: # x and y are arrays def intersection(x;y): ( (x|unique) + (y|unique) | sort) as $sorted | reduce range(1; $sorted|length) as $i ([]; if $sorted[$i] == $sorted[$i-1] then . + [$sorted[$i]] else . end) ;

A simple and quite fast (but somewhat naive) filter that probably does essentially what you want can be defined as follows: # x and y are arrays def intersection(x;y): ( (x|unique) + (y|unique) | sort) as $sorted | reduce range(1; $sorted|length) as $i ([]; if $sorted[$i] == $sorted[$i-1] then . + [$sorted[$i]] else . end) ;

如果在STDIN上提供x作为输入,并且以其他方式提供y(例如def y:...),则可以将其用作:intersection(.; y)

If x is provided as input on STDIN, and y is provided in some other way (e.g. def y: ...), then you could use this as: intersection(.;y)

提供两个不同数组作为输入的其他方法包括:

Other ways to provide two distinct arrays as input include:

 * using the --slurp option
 * using "--arg a v" (or "--argjson a v" if available in your jq)

这是一个简单但较慢的def,但是在实践中却相当快: def i(x;y): if (y|length) == 0 then [] else (x|unique) as $x | $x - ($x - y) end ;

Here's a simpler but slower def that's nevertheless quite fast in practice: def i(x;y): if (y|length) == 0 then [] else (x|unique) as $x | $x - ($x - y) end ;

这是一个独立的过滤器,用于查找任意多个数组的交集:

Here's a standalone filter for finding the intersection of arbitrarily many arrays:

# Input: an array of arrays
def intersection:
  def i(y): ((unique + (y|unique)) | sort) as $sorted
  | reduce range(1; $sorted|length) as $i
       ([]; if $sorted[$i] == $sorted[$i-1] then . + [$sorted[$i]] else . end) ;
  reduce .[1:][] as $a (.[0]; i($a)) ;

示例:

[ [1,2,4], [2,4,5], [4,5,6]] #=> [4]
[[]]                         #=> []
[]                           #=> null

当然,如果已知x和y已排序和/或唯一,则可能会有更有效的解决方案.特别请参见 https://rosettacode.org/wiki/Set#Finite_Sets_of_JSON_Entities

Of course if x and y are already known to be sorted and/or unique, more efficient solutions are possible. See in particular https://rosettacode.org/wiki/Set#Finite_Sets_of_JSON_Entities

这篇关于如何使用jq获取两个JSON数组的交集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆