Recursive functions are functions that call themselves.
A recursive function needs to have at least one base case and at least one recursive case.
A base case returns a value without calling the function again. A recursive case calls the function again, modifying the input so that it will at some point match the base case.
Here is an example that counts the elements of an array.
def count:
if length == 0 then
0 # base case
else
1 + (.[1:] | count) # recursive case
end;
([] | count), # => 0
([11, 22, 33] | count) # => 3
A recursive function can have many base cases and/or many recursive cases. For example the Fibonacci sequence is a recursive sequence with two base cases.
def fibonacci:
if . == 0 then
0
elif . == 1 then
1
else
(. - 1 | fibonacci) + (. - 2 | fibonacci)
end;
10 | fibonacci # => 55
Counting the number of occurrences of some given value x
in a list has two recursive cases.
def count_occurrences(x):
if length == 0 then
0
elif first == x then
1 + (.[1:] | count_occurrences(x))
else
(.[1:] | count_occurrences(x))
end;
[11, 22, 33, 22, 44] | count_occurrences(22) # => 2
In practice, iterating over lists and other enumerable data structures is most often done using builtin functions,
such as map
and reduce
, or by using streams like [.[] | select(...)]
.
Under the hood, some builtins are implemented using recursion.
In this exercise you're going to implement some recursive functions.
We'll re-implement the builtin add
filter to practice recursion.
The base case is that an empty array has a sum of zero.
Implement it yourself with a recursive function; don't use the builtin add
.
[5, 4, 6, 10] | array_add # => 25
We'll re-implement the builtin reverse
filter.
The base case is that an empty array reversed is an empty array.
Implement it yourself with a recursive function; don't use the builtin reverse
.
[5, 4, 6, 10] | array_reverse # => [10, 6, 4, 5]
We'll re-implement the builtin map
filter.
The function takes a filter as a parameter, run that filter for each element of the input array, and return the outputs in a new array.
The base case is that an empty array maps to an empty array.
Implement it yourself with a recursive function; don't use the builtin map
.
[5, 4, 6, 10] | array_map(. + 10) # => [15, 14, 16, 20]
Sign up to Exercism to learn and master jq with 12 concepts, 74 exercises, and real human mentoring, all for free.