在谓词为真时计算元素

时间:2021-07-23 12:43:02

标签: json while-loop jq

我有一个像这样的 JSON 对象集合:

{"id":"da1234563","message":"brown fox jump over a red log"}
{"id":"da1234564","message":"brown fox jump over a red log"}
{"id":"da1234565","message":"brown fox jump over a red log"}
{"id":"da1234566","message":"brown fox jump over a red log"}
{"id":"da1234567","message":"red fox jump over a brown log"}
{"id":"da1234568","message":"another random string"}
{"id":"da1234569","message":"brown fox jump over a red log"}

我想使用 jq 遍历这些对象并返回 brown fox 的跳跃次数,直到找不到匹配项为止。

以下 jq 为我提供了包含棕色狐狸的每一行,包括最后一行:

jq -n 'inputs|select(.message|test("brown fox"))'

如何在不匹配后排除匹配并计算匹配数,以便 jq 仅返回 4

3 个答案:

答案 0 :(得分:2)

另一个类似于@customcommander 的选项,但使用 #include<bits/stdc++.h> using namespace std; int main(){ long n,d,m,s; cin>>n>>d; vector< pair<long ,long> > v; for(long i=0;i<n;i++){ cin>>m>>s; v.push_back( {m,s} ); } sort(v.begin(),v.end()); long ans=0; for(long i=0;i<n;i++){ long j = upper_bound(v.begin(),v.end(), make_pair(v[i].first+d,INT_MIN) ) - v.begin(); long x=0; long f=i; while(f<j){ x+=v[f].second; f+=1; } ans=max(ans,x); } cout<<ans; } 而不是 /usr/include/c++/6/bits/predefined_ops.h:72:22: error: no match for ‘operator<’ (operand types are ‘const std::pair’ and ‘std::pair’) { return __val < *__it; }

until

https://jqplay.org/s/pAyfv7ZvQK

答案 1 :(得分:2)

为了效率,最好避免“slurping”输入,正如 Q 中所设想的那样,在这种情况下可以通过使用 input(或 inputs)和-n 命令行选项。

使用面向流的计数函数和内置的 while

def count(s): reduce s as $x (0; .+1);

count(while (input | .message|test("brown fox"); true) )

另一种选择

def count(s): reduce s as $x (0; .+1);

def select_while(s; cond):
  label $out | s | if cond then . else break $out end;

count( select_while(inputs; .message|test("brown fox") ) )

答案 2 :(得分:0)

使用--slurp

reduce .[] as $i ([0, true]; if .[1] and ($i.message | contains("brown fox")) then .[0] += 1 else .[1] = false end) | .[0]

我使用 [0, true] 来知道何时停止计数:

  1. 布尔值表示我们应该继续计数
  2. 当我们继续匹配“brown fox”时,数字会递增
  3. 但是,一旦我们不这样做,标志就会更改为 false

我确定有更好的方法,但我看不到它;)


https://jqplay.org/s/Art_0y3u_g

相关问题