Reputation:
I wrote following commands:
jq -n 'reduce empty as $e (0; .)'
jq -n 'foreach empty as $e (0; .; .)'
and I was expecting both to yield nothing (or 0, I was expecting consistency between these similar structs). But instead, I got inconsistent results.
$ jq -n 'reduce empty as $e (0; .)'
0
$ jq -n 'foreach empty as $e (0; .; .)'
$
Manual says:
empty returns no results. None at all. Not even null. It's useful on occasion. You'll know if you need it :)
And I interpreted this like it's like a black hole that absorbs everything (I might be wrong). But when it is used as generator, reduce
lets its initial value pass, while foreach
doesn't. I don't know which one is acting logical but I'm at foreach
's side.
I couldn't find any explanation to this difference, and couldn't think of one that makes sense. Can you guys help me understand why reduce
and foreach
behave different when generator is empty
?
Upvotes: 0
Views: 197
Reputation: 134511
Reduce is just a reducing function for a given collection. Given an initial seed, it will update the value for each value and returns the final result.
Foreach is similar to reduce but is different in that it doesn't return the final result, but rather it returns all the intermediate results for each value instead.
Since no iterations are made in the foreach call, no results are generated. Reduce on the other hand also has no iterations so no changes are made to the initial seed (0
) which is then returned.
It's somewhat equivalent to the following python code if this helps:
def reduce(in, get_items, get_seed, update):
current = get_seed(in)
for item in get_items(in):
current = update(current, item)
return current
def foreach(in, get_items, get_seed, update, extract):
current = get_seed(in)
for item in get_items(in):
current = update(current, item)
yield extract(current, item)
Upvotes: 3