差/2
jq の「-」演算子が配列で定義される方法のunique
ため、「一意の」回答を生成するには を 1 回呼び出すだけで十分です。
def difference($a; $b): ($a | unique) - $b;
同様に、対称差の場合、「一意の」値を生成するには、1 回の並べ替え操作で十分です。
def sdiff($a; $b): (($a-$b) + ($b-$a)) | unique;
交差/2
intersect/2
これは、すべてのバージョンの jq で動作group_by
するのより高速なバージョンsort
です。
def intersect(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) ;
交差点/2
jq 1.5 を使用している場合は、同様ですが、かなり高速な set-intersection 関数を次に示します。これは、2 つの配列の set-intersection にある要素のストリームを生成します。
def intersection(x;y):
(x|unique) as $x | (y|unique) as $y
| ($x|length) as $m
| ($y|length) as $n
| if $m == 0 or $n == 0 then empty
else { i:-1, j:-1, ans:false }
| while( .i < $m and .j < $n;
$x[.i+1] as $nextx
| if $nextx == $y[.j+1] then {i:(.i+1), j:(.j+1), ans: true, value: $nextx}
elif $nextx < $y[.j+1] then .i += 1 | .ans = false
else .j += 1 | .ans = false
end )
end
| if .ans then .value else empty end ;