jq-dry
Don't repeat yourself!
⚠️ This project has been archivedNo future updates are planned. Feel free to continue using it, but expect no support.
Apply a filter f
to its own output n
times. Can be used to apply filters n
recursive levels, to build deep objects and for arithmetic.
This is a package for the command-line JSON processor jq
. Install the package in your jq project/package directory with jqnpm
:
jqnpm install joelpurra/jq-dry
Usage
import "joelpurra/jq-dry" as DRY;
# The general case: 'n' is the number of iterations:
# DRY::iterate(n; f)
# Can read both index and value in 'f': [ <iteration index>, <previous value> ]
"a" | iterate(1; .[1] + .[1] + (.[0] | tostring)) # [ 0, "aa0" ]
"a" | iterate(2; .[1] + .[1] + (.[0] | tostring)) # [ 1, "aa0aa01" ]
# The general case: 'n' is the number of repetitions:
# DRY::repeat(n; f)
"YO" | DRY::repeat(3; . + "LO") # "YOLOLOLO"
"LO" | DRY::repeat(3; "YO" + .) # "YOYOYOLO"
# Can recurse into objects 'n' levels deep.
{ "a": { "a": { "a": "deep" } } } | DRY::repeat(2; .a) # { "a": "deep" }
{ "a": { "a": { "a": "deep" } } } | DRY::repeat(3; .a) # "deep"
# Can build objects 'n' levels deep.
"deep" | DRY::repeat(2; { a: . }) # { "a": { "a": "deep" } }
"deep" | DRY::repeat(3; { a: . }) # { "a": { "a": { "a": "deep" } } }
# Can recurse into arrays 'n' levels deep.
[ 1, [ 2, [ 3, 4 ], 5 ], 6 ] | DRY::repeat(2; .[1]) # [ 3, 4 ]
[ 1, [ 2, [ 3, 4 ], 5 ], 6 ] | DRY::repeat(3; .[1]) # 4
# Can build arrays 'n' levels deep.
"deep" | DRY::repeat(2; [ . ]) # [ [ "deep" ] ]
"deep" | DRY::repeat(3; [ . ]) # [ [ [ "deep" ] ] ]
# Shortcuts for some jq builtins, and what they make sense to use with:
# objA | DRY::addition(n; objB) for numbers, arrays, strings.
# Also works as '+' for objects, but it makes no sense to repeat it.
# The name is 'addition' because 'add' is already a jq builtin.
2 | DRY::addition(4; 3) # 14
"a" | DRY::addition(2; "bc") # "abcbc"
[ "a" ] | DRY::addition(2; [ "b" ]) # [ "a", "b", "b" ]
# DRY::subtract(n; obj) for numbers.
# Also works as '-' for arrays, but it makes no sense to repeat it.
# Effectively: numA - (n times numB).
14 | DRY::subtract(4; 3) # 2
# numA | DRY::multiply(n; numB) for numbers.
# Also works as '*' for objects, but it makes no sense to repeat it.
# Effectively: numA times (numB to the power of n).
1 | DRY::multiply(10; 2) # 1024
# numA | DRY::divide(n; numB) for numbers.
# Effectively: numA divided with (numB to the power of n).
81 | DRY::divide(2; 3) # 9
# numA | DRY::sqrt(n; numB) for numbers.
# Effectively: sqrt(numA) to the power of n.
# Equals: (numA to the power of 1/2) to the power of n.
81 | DRY::sqrt(2) # 3
# Combining repetitions can be fun, if somewhat complex and confusing.
# More -- and better -- examples welcome!
1 | DRY::addition(2; DRY::addition(3; 4)) # 40 (1 + (((1 + 4) + 4) + 4) + (((1 + (((1 + 4) + 4) + 4) + 4) + 4) + 4))
"a" | DRY::addition(2; DRY::addition(2; "b")) # "aabbaabbbb" ("a" + (("a" + "b") + "b") + (("a" + (("a" + "b") + "b") + "b") + "b"))
# Fibonacci number 'n' using repeat.
[ 0, 1 ] | DRY::repeat(0; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 0
[ 0, 1 ] | DRY::repeat(1; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 1
[ 0, 1 ] | DRY::repeat(2; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 1
[ 0, 1 ] | DRY::repeat(3; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 2
[ 0, 1 ] | DRY::repeat(4; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 3
[ 0, 1 ] | DRY::repeat(5; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 5
[ 0, 1 ] | DRY::repeat(6; [ .[1], ( .[0] + .[1] ) ] ) | .[0] # 8
# Or the equivalent function and iteration:
def fib($n):
[ 0, 1 ]
| DRY::repeat(
$n;
[
.[1],
(
.[0]
+ .[1]
)
]
)
| .[0];
# In terms of number of calculations this is a poor implementation.
# Again -- better examples welcome =)
[]
| DRY::iterate(7; .[1] + [ fib(.[0]) ])
| .[1]
License
Copyright (c) 2015 Joel Purra https://joelpurra.com/ All rights reserved.
When using jq-dry, comply to the MIT license. Please see the LICENSE file for details.