$ jq -n '$ARGS.positional as $list | $list[$list | indices("3")[] + 1]' --args 3 1 2 3 A B C 3
"1"
"A"
null
The command returns the elements after any element in the input that is 3. In the example, the input is the list of strings given at the end of the command line, and the output shows that the strings 1 and A occur after the string 3 in the input. There is also a null value outputted as there is a 3 at the very end of the input list.
The command works by using indices() to return a list of indices of values equal to 3, adding 1 to each of them, and using the result as an index into the original list.
The following is a reformulation of the above on a form similar to that in the question:
jq -n '$ARGS.positional as $list | ($list | indices("3")[]) as $id | $list[$id + 1]' --args 3 1 2 3 A B C 3
The ... as $id is a loop over the indices that correspond to values that are 3 in the input list. The body of the loop, $list[$id + 1], extracts the value after the given index.
By moving the array expansion from indices("3")[] to where $id is used, we turn $id into an array, and the "loop" is demoted into a multi-valued index instead:
jq -n '$ARGS.positional as $list | ($list | indices("3")) as $id_list | $list[$id_list[] + 1]' --args 3 1 2 3 A B C 3
With an array of objects as input, we would need to compare with an object too:
$ cat file
[
{"thing":"3"},
{"thing":"1"},
{"thing":"2"},
{"thing":"3"},
{"thing":"A"},
{"thing":"B"},
{"thing":"C"},
{"thing":"3"}
]
$ jq '. as $list | (indices({thing: "3"})) as $id_list | $list[$id_list[] + 1]' file
{
"thing": "1"
}
{
"thing": "A"
}
null
As you may imagine, this becomes a bit unwieldy if the array entries are complex and you only care for smaller parts of them; it's difficult to generalise.
This is fixed by extracting the interesting bits and using indices() on them (and at the same time, I'm dropping the creation of the variable $id_list, as it's strictly not needed):
$ cat file
[
{"thing":"3", "other bits": "unimportant"},
{"thing":"1", "other bits": "unimportant"},
{"thing":"2", "other bits": "unimportant"},
{"thing":"3", "other bits": "unimportant"},
{"thing":"A", "other bits": "unimportant"},
{"thing":"B", "other bits": "unimportant"},
{"thing":"C", "other bits": "unimportant"},
{"thing":"3", "other bits": "unimportant"}
]
$ jq '. as $list | map_values(.thing == "3") | indices(true) | $list[.[] + 1]' file
{
"thing": "1",
"other bits": "unimportant"
}
{
"thing": "A",
"other bits": "unimportant"
}
null
Then you'll do what every programmer would do, which is to abstract away the details into a function:
def select_indices(f): map_values(f) | indices(true);
... and call that instead
. as $list | select_indices(.thing == "3") | $list[.[] + 1]