mirror of
https://github.com/adambard/learnxinyminutes-docs.git
synced 2024-12-23 09:41:36 +00:00
Introduce function definition, and add more examples.
This commit is contained in:
parent
2257d6bae2
commit
0ef85542ef
@ -362,7 +362,7 @@ jq -n '.unknown_key // 7' # => 7
|
||||
jq -n '123 | .[0]' # => jq: error (at <unknown>): Cannot index number with number
|
||||
jq -n '"abc" | .name' # => jq: error (at <unknown>): Cannot index string with string "name"
|
||||
jq -n '{"a": 97} | .[0]' # => jq: error (at <unknown>): Cannot index object with number
|
||||
jq -n '[89, 64] | .["key"]' # => jq: error (at <unknown>): Cannot index array with string "key"
|
||||
jq -n '[89, 64] | .["key"]' # => jq: error (at <unknown>): Cannot index array with string "key"
|
||||
|
||||
# You can, however, append a `?` to a lookup to make jq return `empty`
|
||||
# instead when such error happens.
|
||||
@ -443,7 +443,19 @@ jq -n '{ values: ({ a: 1, b: 2, c: 3 }[] | . * 2) }'
|
||||
|
||||
|
||||
# Conditional `if ... then ... else ... end` in jq is an expression, so
|
||||
# both the `then` part and the `else` part are required.
|
||||
# both the `then` part and the `else` part are required. In jq, only
|
||||
# two values, `null` and `false`, are false; all other values are true.
|
||||
#
|
||||
jq -n 'if 1 > 2 | not and 1 <= 2 then "Makes sense" else "WAT?!" end'
|
||||
|
||||
# Output
|
||||
# "Makes sense"
|
||||
|
||||
# Notice that `not` is a built-in function that takes zero arguments,
|
||||
# that's why it's used as a filter to negate its input value.
|
||||
# We'll talk about functions soon.
|
||||
|
||||
# Another example using a conditional:
|
||||
#
|
||||
jq -n '1, 2, 3, 4, 5 | if . % 2 != 0 then . else empty end'
|
||||
|
||||
@ -608,7 +620,7 @@ echo $numbers | jq -rs ' # Slurp the numbers into an array.
|
||||
| # For each object, generate two lines:
|
||||
"Group \(.key): \(.value | sort | join(" "))" + "\n" +
|
||||
"Average: \( .value | (add / length) )"
|
||||
|
||||
|
||||
] # Contain the group+average lines in an array.
|
||||
# Join the array elements by separator lines (dashes) to produce the report.
|
||||
| join("\n" + "-"*78 + "\n")
|
||||
@ -682,7 +694,7 @@ jq -n '["a", "b", "c"] | reduce .[] as $i (""; . + $i)' # => "abc"
|
||||
#
|
||||
# reduce (1, 2, 3, 4, 5) as $i (0; . + $i)
|
||||
#
|
||||
# can be think of as doing:
|
||||
# can be think of as doing:
|
||||
#
|
||||
# 0 + 1 | . + 2 | . + 3 | . + 4 | . + 5
|
||||
#
|
||||
@ -730,7 +742,7 @@ jq -rn '[1, 2, 3, 4, 5]
|
||||
# With the `expr as $var` form, if multiple values are generated by `expr`
|
||||
# then jq will iterate through them and bind each value to `$var` in turn
|
||||
# for the rest of the pipeline.
|
||||
#
|
||||
#
|
||||
jq -rn 'range(2; 4) as $i
|
||||
| range(1; 6) as $j
|
||||
| "\($i) * \($j) = \($i * $j)"
|
||||
@ -749,6 +761,26 @@ jq -rn 'range(2; 4) as $i
|
||||
# 3 * 5 = 15
|
||||
|
||||
|
||||
# It's sometimes useful to bind the initial input to a variable at the
|
||||
# start of a program, so that you can refer to it later down the pipeline.
|
||||
#
|
||||
jq -rn "$(cat <<'EOF'
|
||||
{lookup: {a: 1, b: 2, c: 3},
|
||||
bonuses: {a: 5, b: 2, c: 9}
|
||||
}
|
||||
| . as $doc
|
||||
| .bonuses
|
||||
| to_entries[]
|
||||
| "\(.key)'s total is \($doc.lookup[.key] + .value)"
|
||||
EOF
|
||||
)"
|
||||
|
||||
# Output:
|
||||
# a's total is 6
|
||||
# b's total is 4
|
||||
# c's total is 12
|
||||
|
||||
|
||||
# In jq, values can be assigned to an array index or object key via the
|
||||
# assignment operator, `=`. The same current input is given to both sides
|
||||
# of the assignment operator, and the assignment itself evaluates to the
|
||||
@ -761,7 +793,7 @@ jq -n '.a = 1 | .b = .a + 1' # => {"a": 1, "b": 2}
|
||||
# filter, and assiging to a key under `null` turns it into an object with
|
||||
# the key. The same input (now an object) then gets piped to the next filter,
|
||||
# which then sets the `b` key to the value of the `a` key plus `1`, which is `2`.
|
||||
#
|
||||
#
|
||||
|
||||
# Another example:
|
||||
#
|
||||
@ -799,9 +831,43 @@ jq -n '{a: 1, b: {c: 2}, d: [3, 4, 5]} | del(.b.c, .d[1]) | .b.x = 6'
|
||||
# ]
|
||||
# }
|
||||
|
||||
# FIXME: Cover more topics
|
||||
# - function definition
|
||||
# - ...
|
||||
|
||||
# Other than using jq's built-in functions, you can define your own.
|
||||
# In fact, many built-in functions are defined using jq (see the link
|
||||
# to jq's built-in functions at the end of the doc).
|
||||
#
|
||||
jq -n '
|
||||
def my_select(expr): if expr then . else empty end;
|
||||
def my_map(expr): [.[] | expr];
|
||||
def sum: reduce .[] as $x (0; . + $x);
|
||||
def my_range($from; $to):
|
||||
if $from >= $to then
|
||||
empty
|
||||
else
|
||||
$from, my_range($from + 1; $to)
|
||||
end
|
||||
;
|
||||
[my_range(1; 6)] | my_map(my_select(. % 2 != 0)) | sum
|
||||
'
|
||||
|
||||
# Output:
|
||||
# 9
|
||||
|
||||
# Some notes about function definitons:
|
||||
#
|
||||
# - Functions are usually defined at the beginning, so that they are available
|
||||
# to the rest of the jq program.
|
||||
#
|
||||
# - Each function definion should end with a `;` (semicolon).
|
||||
#
|
||||
# - It's also possible to define a function within another, though it's not shown here.
|
||||
#
|
||||
# - Function parameters are separated by `;` (semicolor). This is consistent with
|
||||
# passing multiple arguments when calling a function.
|
||||
#
|
||||
# - `def f($a; $b): ...;` is a shorthand for: `def f(a; b): a as $a | b as $b | ...`
|
||||
#
|
||||
|
||||
```
|
||||
|
||||
## Further Reading
|
||||
|
Loading…
Reference in New Issue
Block a user