This guide still mentions several features/examples for `Jeff` (jf), which is short for `Json Formulas`, a previous tool which has its own custom source-code parser. Ignore those examples.
Here are several examples of GoTron expressions and their results, along with some complete scripts and commands you can run as given.
GoTron/gt (GO TRansform jsON) is just a command-line app which lets you view, transform, and JSON data. Input data come from standard input by default, unless named filepaths/URIs are given to load valid JSON from.
GoTron uses golang-syntax formulas/expressions to transform data, which are run using a surprisingly capable scripting engine. If the command is a dot, it means keep input data as they are. Scripts give you all sorts of conveniences you may have come to expect from other popular tools, such as negative indexing, but that's barely scratching the surface: `gt` gives you many other handy features, such as automatic depth-first recursion for most operators and functions.
Scripts can use 100+ predefined funcs, not counting aliases; plenty of global variables with all sorts of data are also available. Some of these predefined functions/values are documented on this help page. Many names/aliases should be familiar if you know JavaScript, Go, or Python: just avoid package names, avoid underscores, keep all letters lowercase, and you'll often get the right GoTron names for what you need.
As frequently shown here, the most convenient way to call 1-input funcs on non-objects is to use them as fake-properties of their input. Since objects have real properties, you have to use parentheses to call funcs explicitly on them, as many examples show.
Here are all value-types supported.
null | null value |
boolean | true or false |
number | 64-bit floating-point number, with NaN, +inf, and -inf |
string | plain-text encoded as UTF-8 |
array | arbitrary-length list of values; also called `list` |
object | ordered associative array with string keys |
value . func (args...) | fake-method function call |
`abc`.upper() | "ABC" |
10.0.log10() | 1 |
10..log10() | 1 |
10i.log10() | 1 |
10i.sqrt().log10() | 0.5 |
(1 ^ 3).sqrt().tofixed(3) | ["1.000", "1.414", "1.732"] |
nonobject . function | fake-property function call |
`abc`.upper | "ABC" |
10.0.log10 | 1 |
10..log10 | 1 |
10i.log10 | 1 |
10i.sqrt.log10 | 0.5 |
(1 ^ 3).sqrt.fix3 | ["1.000", "1.414", "1.732"] |
object . property | object-property access |
monthlen . January | 31 |
[:] | exclusive slice syntax |
"abcπdef"[2:5] | "cπd" |
"aπbc"[:1^3] | ["a", "aπ", "aπb"] |
monthlen[`February`:`March`] | {"February": 28} |
monthlen[:`March`] | {"January": 31, "February": 28} |
! | boolean negation |
!false | true |
!true | false |
!0 | true |
!-1.5 | false |
!nan | false |
+ | convert to number |
+false | 0 |
+true | 1 |
+123.456 | 123.456 |
+nan | NaN |
+"abc" | NaN |
+"123.456" | 123.456 |
- | negate number(s) |
-(-1.5) | 1.5 |
-nan | NaN |
-a(1, 2, 3) | [-1, -2, -3] |
-_{a: 1, b: 2} | {"a": -1, "b": -2} |
+ | addition, or string concatenation |
3 + 4.5 | 7.5 |
4.5 + "abc" | "4.5abc" |
"abc" + 4.5 | "abc4.5" |
"some" + "text" | "sometext" |
3 + a(4.5, "abc") | [7.5, "3abc"] |
a(4.5, "abc") + 3 | [7.5, "abc3"] |
3 + _{a: 4.5, b: "abc"} | {"a": 7.5, "b": "3abc"} |
_{a: 4.5, b: "abc"} + 100 | {"a": 104.5, "b": "abc100"} |
- | subtraction, or substring removal |
3 - 4.5 | -1.5 |
"sassy" - "ss" | "say" |
"something" - "methi" | "song" |
"excellent" - "e" | "xcllnt" |
3 - a(4.5, 1) | [-1.5, 1] |
3 - _{a: 4.5, b: 1} | {"a": -1.5, "b": 2} |
* | multiplication, or string repetition |
3 * 4.5 | 13.5 |
3.9 * "-" | "---" |
"abc" * 3.9 | "abcabcabc" |
3 * a(4.5, 1) | [13.5, 3] |
_{a: 4.5, b: 1} * 3 | {"a": 13.5, "b": 3} |
3 * _{a: 4.5, b: 1} | {"a": 13.5, "b": 3} |
_{a: 4.5, b: 1} * 3 | {"a": 13.5, "b": 3} |
/ | division, chunking strings, or splitting strings |
4.5 / 3 | 1.5 |
"abcdef" / 3 | ["ab", "cd", "ef"] |
"abcdef" / 2 | ["abc", "def"] |
"πππππ" / 2 | ["πππ", "ππ"] |
2 / "πππππ" | ["ππ", "ππ", "π"] |
2 / "abcdef" | ["ab", "cd", "ef"] |
"abc,def,xyz" / "," | ["abc", "def", "xyz"] |
"," / "abc,def,xyz" | [","] |
"πππππ" / "" | ["π", "π", "π", "π", "π"] |
3 / a(4.5, 1) | [0.6666666666666666, 3] |
a(4.5, 1) / 3 | [1.5, 0.3333333333333333] |
3 / _{a: 4.5, b: 1} | {"a": 0.6666666666666666, "b": 3} |
_{a: 4.5, b: 1} / 3 | {"a": 1.5, "b": 0.3333333333333333} |
^ | number sequencing, array joining, or object flattening |
-3 ^ -3 | [-3] |
3 ^ 6.2 | [3, 4, 5, 6] |
3.25 ^ -2.2 | [3.25, 2.25, 1.25, 0.25, -0.75, -1.75] |
a("a", "b", "c") ^ "" | "abc" |
"" ^ a("a", "b", "c") | "abc" |
"; " ^ a("a", "b", -7, "c") | "a; b; -7; c" |
a("a", "b", "c") ^ a(1, 2, 3) | {"a": 1, "b": 2, "c": 3} |
a(-20, 12.75, "hey, hi!") ^ a(1, 2) | {"-20": 1, "12.75": 2, "hey, hi!": null} |
_{"data": {"abc.json": 1024}, "info.txt": 321} ^ "/" |
{"data/abc.json": 1024, "info.txt": 321} |
_{"a": {"b": 1, "c": 2}, "d": 3} ^ "/" | {"a/b": 1, "a/c": 2, "d": 3} |
&& | boolean and |
true && false | false |
|| | boolean or |
true || false | true |
| | fail-pipes |
4 | 7 | 4 |
2i.abc | 4 | 4 |
& | ok-pipes |
4 & 7 | 4 |
mixing operators | |
"a b c" / " " ^ "," | "a,b,c" |
"πππππ" / 3 ^ "\n" | "ππ\nππ\nπ" |
[index/slice] | 0-based indexing |
"abc"[1] | "b" |
"abc"[-1] | "c" |
a(1, 2, 3)[1] | 2 |
a(1, 2, 3)[-1] | 3 |
_{a: 1, b: 2, c: 3}[2] | 3 |
_{a: 1, b: 2, c: 3}[-1] | 3 |
_{a: 1, b: 2, c: 3}["a"] | 1 |
_{a: 1, b: 2, c: 3}["d"] | null |
: | 0-based exclusive slicing |
a(1, 2, 3)[:2] | [1, 2] |
a(1, 2, 3)[0:2] | [1, 2] |
a(1, 2, 3)[:] | [1, 2, 3] |
_{a: 1, b: 2, c: 3}[:] | [1, 2, 3] |
_{a: 1, b: 2, c: 3}[:2] | {"a": 1, "b": 2} |
_{a: 1, b: 2, c: 3}[:-1] | {"a": 1, "b": 2} |
_{a: 1, b: 2, c: 3}[:-2] | {"a": 1} |
_{a: 1, b: 2, c: 3}[:"b"] | {"a": 1} |
_{a: 1, b: 2, c: 3}[:"c"] | {"a": 1, "b": 2} |
^ | sequencing |
3^5 | [3, 4, 5] |
4.25 ^ 0.9 | [4.25, 3.25, 2.25, 1.25] |
abs | absolute value |
false.abs | 0 |
true.abs | 1 |
(-4.234).abs | 4.234 |
acos | arc cosine, inverse cosine |
acosh | hyperbolic arc cosine |
array | make an array/list of values |
array() | [] |
array(null, -3, "hi") | [null, -3, "hi"] |
array(-3.2, ["abc", null]) | [-3.2, ["abc", null]] |
array(-3.2, ["abc", null], _{a: 34, b: nan}) | [-3.2, ["abc", null], {"a": 34, "b": nan}] |
array(4, 5, 6, 7, 8) | [4, 5, 6, 7, 8] |
asin | arc sine, inverse sine |
asinh | hyperbolic arc sine |
assign, update | update/override object key-value pairs |
_{a: 2, b: 3}.assign(_{a: 1, c: 9}) | {"a": 1, "b": 3, "c": 9} |
_{a: 2, b: 3}.assign(_{a: 1, c: 9}, _{c: null}) | {"a": 1, "b": 3, "c": null} |
atan | arc tangent, inverse tangent |
atanh | hyperbolic arc tangent |
basename | get filename without preceding folders |
"folder/file.txt".basename | "file.txt" |
beta | beta function |
beta(1, 2) | 0.5 |
bin | convert number into string of binary digits |
333.bin | "101001101" |
bool, boolean | make a boolean |
null.bool | false |
false.bool | false |
0.bool | false |
"".bool | false |
a().bool | false |
_{}.bool | false |
true.bool | true |
(-3).bool | true |
123.456.bool | true |
nan.bool | true |
"abc".bool | true |
[false].bool | true |
_{a: false}.bool | true |
break | break a container into n parts, or fewer |
"abcdefghi".break(2) | ["abcde", "fghi"] |
"πππππ".break(2) | ["πππ", "ππ"] |
a(1, 2, 3, 4, 5).break(3) | [[1, 2], [3, 4], [5]] |
monthlen.break(2) | [ {"January": 31, "February": 28, "March": 31, "April": 30, "May": 31, "June": 30}, {"July": 31, "August": 31, "September": 30, "October": 31, "November": 30, "December": 31} ] |
cbrt | cube root |
27.cbrt | 3 |
ceil, ceiling | round numbers up |
3.3.ceil | 4 |
century | round down by 100s |
1995.century | 1,900 |
chars, runes | split a string into an array of 1-item strings |
"".chars | [] |
"abcdef".chars | ["a", "b", "c", "d", "e", "f"] |
"πππππ".chars | ["π", "π", "π", "π", "π"] |
"ππ\nπ\nππ".chars | ["π", "π", "\n", "π", "\n", "π", "π"] |
chr | |
65.chr | "A" |
chunk | break a container into parts, each up to the length given |
"abcdef".chunk(3.8) | ["abc", "def"] |
"πππππ".chunk(2) | ["ππ", "ππ", "π"] |
"πππππ".chunk(3) | ["πππ", "ππ"] |
a(1, 2, 3, 4, 5, 6, 7, 8).chunk(2) | [[1, 2] [3, 4], [5, 6], [7, 8]] |
a(1, 2, 3, 4, 5, 6, 7, 8).chunk(3) | [[1, 2, 3], [4, 5, 6], [7, 8]] |
monthlen.chunk(3) | [ {"January": 31, "February": 28, "March": 31}, {"April": 30, "May": 31, "June": 30}, {"July": 31, "August": 31, "September": 30}, {"October": 31, "November": 30, "December": 31} ] |
concat, concatenate | concatenate into a string |
contains | does a string contain the substring given? |
"abc # 123".contains("# ") | true |
cos | cosine |
(pi / 2).cos | 0 |
cosh | hyperbolic cosine |
(pi / 2).cosh | 2.5091784786580567 |
decade | round down by 10s |
1995.decade | 1,990 |
dedup, set, unique | ignore repeating array items |
a(3, 2, "3", 1, 3, "hi!").dedup | [3, 2, "3", 1, "hi!"] |
deg, degrees | turn radians into angular degrees |
(pi / 4).degrees | 45 |
pi.degrees | 180 |
dehtml, unhtml | unescape/decode HTML symbol-aliases |
"Tom & Jerry".dehtml | "Tom & Jerry" |
deinf | replace either number infinity with any alternative |
null.deinf(0) | null |
false.deinf(null) | false |
0.deinf(null) | 0 |
(-inf).deinf(null) | null |
inf.deinf(null) | null |
"".deinf(null) | "" |
a().deinf(null) | [] |
_{}.deinf(null) | {} |
del, delete, drop | remove keys from object |
_{a: 123, b: 456}.del("a") | {"b": 456} |
_{a: 123, b: 456}.del("a", "b", "c") | {} |
dirname | get directory/folder name |
"folder/file.txt".dirname | "folder" |
dumps, json, stringify | turn any supported value into a JSON string |
a(1, 2, "abc").json | "[1, 2, \"abc\"]" |
dup | |
null.dup(5) | [null, null, null, null, null] |
false.dup(5) | [false, false, false, false, false] |
4.dup(10) | [4, 4, 4, 4, 4, 4, 4, 4, 4, 4] |
a("~").dup(5) | ["~", "~", "~", "~", "~"] |
a().dup(10) | [] |
[4].dup(10) | [4, 4, 4, 4, 4, 4, 4, 4, 4, 4] |
a(1, 2).dup(4) | [1, 2, 1, 2, 1, 2, 1, 2] |
a(1, 2).dup(-43) | [] |
endswith, hassuffix | check if a string ends as indicated |
"line\r".endswith("\r") | true |
"line".endswith("\r") | false |
equalfold | are 2 strings equal when ignoring unicode-casing? |
"TeXt".equalfold("text") | true |
erf | error function |
erfc | complementary error function |
err, error, fail | raise an error using the string given |
exp | exponential function |
0.exp | 1 |
1.exp | 2.718281828459045 |
ext | get the file extension from a path |
"folder/file.txt".ext | ".txt" |
exp2, pow2 | 2**x |
2.pow2 | 8 |
exp10, pow10 | 10**x |
3.pow10 | 1,000 |
expm1 | e**x - 1, more accurately |
1.expm1 | 1.7182818284590451 |
fields, words | trim a string, then split it on runs of 1 or more spaces |
" abc 123 xy ".fields | ["abc", "123", "xy"] |
" 123 abc def".fields | ["123", "abc", "def"] |
fix, fixed, tofixed | turn number into a string rounded to n decimals |
123_456.7890123.fix(4) | "123456.7890" |
fix0, ..., fix9 | turn number into a string rounded to n decimals |
123_456.7890123.fix0 | "123457" |
123_456.7890123.fix1 | "123456.8" |
123_456.7890123.fix2 | "123456.79" |
123_456.7890123.fix3 | "123456.789" |
123_456.7890123.fix4 | "123456.7890" |
123_456.7890123.fix5 | "123456.78901" |
123_456.7890123.fix6 | "123456.789012" |
flat, flatten | turn array into a shallow one |
a(3, a(4, 5), a("abc")).flat | [3, 4, 5, "abc"] |
float, n, number | turn value into a (float64) number |
false.n | 0 |
true.n | 1 |
123.456.n | 123.456 |
nan.n | NaN |
"abc".n | NaN |
"123.456".n | 123.456 |
floor | round numbers down |
folds, foldstr, foldstring | wrap string into lines using the (optional) max width given |
gamma | gamma function |
pi.gamma | 2.288037795340032 |
1.gamma | 1 |
2.gamma | 1 |
3.gamma | 2 |
4.gamma | 6 |
5.gamma | 24 |
getattr | get attribute, or null, or the fallback value given |
_{"a": 123}.getattr("abc") | null |
_{"a": 123}.getattr("abc", nan) | NaN |
hasattr, hasattrs, haskey, haskeys | check if object has all the keys given, or any keys |
_{}.hasattrs() | false |
_{a: 123}.hasattrs() | true |
_{a: 123}.hasattrs("abc") | false |
_{a: 123, b: null}.hasattrs("a", "b") | true |
hasprefix, startswith | check if a string starts as indicated |
"# comment".hasprefix("# ") | true |
"abc # 123".hasprefix("# ") | false |
hex | convert number into string of hexadecimal digits |
333.hex | "14d" |
hms2s | parse time-duration strings into seconds |
"1:23:45:56.23".hms2s | 171,956.23 |
hypot | multi-dimensional hypothenuse |
hypot(3, 4) | 5 |
hypot(3, 4, 52.8) | 53.03621404285943 |
in | is a value in a container? |
indexes, indices | make an array with numbers 0 .. n-1 |
-3.1.indices | [] |
0.9.indices | [] |
3.99.indices | [0, 1, 2] |
a(inf, nan).indices | [0, 1] |
_{a: 4.5, b: 1}.indices() | [0, 1] |
isinf | check for either infinity |
null.isinf | false |
false.isinf | false |
nan.isinf | false |
"abc".isinf | false |
a(inf, nan).isinf | false |
_{a: inf, b: nan}.isinf | false |
inf.isinf | true |
(-inf).isinf | true |
isnan | check for NaN |
null.isnan | false |
false.isnan | false |
inf.isnan | false |
(-inf).isnan | false |
"abc".isnan | false |
a(inf, nan).isnan | false |
_{a: inf, b: nan}.isnan | false |
nan.isnan | true |
join | join array items using a separator string |
a("a", "b", "c", 1, 2, 3).join | "abc123" |
a("a", "b", "c").join("") | "abc" |
"".join(a("a", "b", "c")) | "abc" |
"; ".join(a("a", "b", -7, "c")) | "a; b; -7; c" |
j0 | 0th-order bessel j function |
j1 | 1st-order bessel j function |
jn(n, x) | nth-order bessel j function |
lbeta | log-beta function |
lbeta(1, 2) | -0.6931471805599453 |
len, length | count number of items |
"abcdef".len | 6 |
"πππππ".len | 5 |
a(1, 2, 3, 550, -2).len | 5 |
_{a: null, b: "hi!"}.len | 2 |
lgamma | log-gamma function |
ln, log | natural logarithm |
1.ln | 0 |
e.ln | 1 |
e.log | 1 |
loads, parse, parsejson | parse a JSON string |
"{\"a\": 1, \"b\": 2}".parse | {"a": 1, "b": 2} |
log(base, x) | logarithm in the base given |
log(2, 8) | 3 |
log1p | ln(1 + x), to calculate interest more accurately |
0.05.log1p | 0.0487901641694320 |
log2 | logarithm in base 2 |
1_024.log2 | 10 |
log10 | logarithm in base 10 |
1_000_000.log10 | 6 |
logistic | logistic function |
(-inf).logistic | 0 |
0.logistic | 0.5 |
inf.logistic | 1 |
lower, tolower, tolowercase | unicode-lowercase string |
"AbCdE".lower | "abcde" |
"NO SHOUTING, PLEASE!".lower | "no shouting, please!" |
lstrip, ltrim | remove leading whitespace in a string |
" abc".lstrip | "abc" |
match, matches | match strings to RE2-style regular expressions |
" xyyyz".matches("xy*z") | true |
" xyyyz".matches("^xy*z") | false |
max | maximum function, accepts any # of args |
max(-3.4) | -3.4 |
max(-3.4, -1_000) | -3.4 |
max(-3.4, -34, 49.4) | 49.4 |
min | minimum function, accepts any # of args |
min(-3.4, -3453, 49.4, 30) | -3453 |
mod | modulus function |
3.5.mod(2) | 1.5 |
name2mime | guess MIME type from a filepath |
"folder/file.mp3".name2mime | "audio/mpeg" |
"folder/file.mp4".name2mime | "video/mp4" |
"folder/file.JPG".name2mime | "image/jpeg" |
neg, negate | negate number(s) |
(-1.5).neg | 1.5 |
nan.neg | NaN |
a(1, 2, 3).neg | [-1, -2, -3] |
_{a: 1, b: 2}.neg() | {"a": -1, "b": -2} |
not | negate boolean |
false.not | true |
true.not | false |
0.not | false |
-3.542.not | false |
nan.not | false |
pow, power | x**y, the power function |
2.5.pow(-1.5) | 0.2529822128134703 |
3.pow(a(4.5, 1)) | [140.29611541307906, 3] |
a(4.5, 1).pow(3) | [91.125, 1] |
3.pow(_{a: 4.5, b: 1}) | {"a": 140.29611541307906, "b": 3} |
_{a: 4.5, b: 1}.pow(3) | {"a": 91.125, "b": 3} |
r0, .., r9, round0, .., round9 | round number to n decimal digits |
123_456.7890123.r0 | 123,457 |
123_456.7890123.r1 | 123,456.8 |
123_456.7890123.r2 | 123,456.79000000001 |
123_456.7890123.r3 | 123,456.78900000000 |
123_456.7890123.r4 | 123,456.78900000000 |
123_456.7890123.r5 | 123,456.78901000001 |
123_456.7890123.r6 | 123,456.78901199999 |
rad, radians | turn angular degrees into radians |
90.rad | 1.570796326794897 |
rep, repeat | |
"~".rep(-40) | "" |
"~".rep(5) | "~~~~~" |
"~".rep(5, "-") | "~-~-~-~-~" |
replace, replaceall | substitute all substring occurrences |
"a b c".replace(" ") | "abc" |
rev, reverse | reverse items |
"πππππ".reverse | "πππππ" |
a(1, 2, 3).reverse | [3, 2, 1] |
_{a: 1, b: 2}.reverse() | {b: 2, a: 1} |
round | round numbers |
21.3.round | 21 |
21.8.round | 22 |
round | round to the number of decimals given |
21.25.round(0) | 21 |
21.25.round(1) | 21.3 |
21.25.round(2) | 21.25 |
rstrip, rtrim | remove trailing whitespace in a string |
"123 e \r".rstrip | "123 e" |
sin | sine |
pi.sin | 0 |
(pi / 2).sin | 1 |
sinh | hyperbolic sine |
(pi / 2).sinh | 2.301298902307295 |
split | split a string on the separator given |
"abc,def,xyz".split(",") | ["abc", "def", "xyz"] |
"abcdef".split("") | ["a", "b", "c", "d", "e", "f"] |
"πππππ".split("") | ["π", "π", "π", "π", "π"] |
sqrt | square root |
2.sqrt | 1.4142135623730951 |
squeeze | trim surrounding whitespace and squeeze multiple spaces |
" 123 e\r\n".squeeze | "123 e" |
s, str, string, tostring | turn a value into a string |
null.str | "null" |
true.str | "true" |
-3.75.str | "-3.75" |
"abc".str | "abc" |
a(123, "abc").str | "[123,"abc"] |
_{"a": 1, "b": true}.str() | "{a:1,b:true}" |
strip, trim | remove surrounding whitespace |
" 123 e\r\n".strip | "123 e" |
tan | tangent |
(pi / 4).tan | 1 |
tanh | hyperbolic tangent |
(pi / 4).tanh | 0.6557942026326724 |
textafter | remove all text up to the end of the substring given |
"abcdef".textafter("bc") | "def" |
"abcdef".textafter("xyz") | "" |
textbefore | remove all text starting from the substring given |
"abcdef".textbefore("bc") | "a" |
"abcdef".textbefore("xyz") | "abcdef" |
title | turn string into a title-cased one |
"breakfast in america".titled | "Breakfast In America" |
"NO SHOUTING, PLEASE!".title | "No Shouting, Please!" |
tofixed | turn number into a string rounded to n decimals |
123_456.7890123.tofixed(0) | "123457" |
123_456.7890123.tofixed(1) | "123456.8" |
123_456.7890123.tofixed(2) | "123456.79" |
123_456.7890123.tofixed(3) | "123456.789" |
toupper, touppercase, upper | unicode-uppercase string |
"AbCdE".upper | "ABCDE" |
"No shouting, please!".upper | "NO SHOUTING, PLEASE!" |
tr, transpose, transposed | switch nesting of values |
a({a: 123, b: 456}, {a: 789, b: null}).tr | {"a": [123, 789], "b": [456, null]} |
trim, trimmed, trimspace | remove surrounding whitespace |
" 123 e\r\n".trim | "123 e" |
trimbefore | remove all text up to the end of the substring given |
"abcdef".trimbefore("bc") | "a" |
"abcdef".trimbefore("xyz") | "abcdef" |
trimdec, trimdecs, trimdecimals | remove excessive trailing zeros after a dot |
"123,456,000".trimdec | 123,456,000 |
"123,456.0000".trimdec | 123,456 |
"123,456.789000".trimdec | 123,456.789 |
trimend | remove trailing whitespace in a string |
"123 e \r".trimend | "123 e" |
textbefore | remove all text starting from the substring given |
"abcdef".textbefore("bc") | "a" |
"abcdef".textbefore("xyz") | "abcdef" |
trimprefix | remove starting substring, if present |
"# comment".trimprefix("# ") | "comment" |
"abc # 123".trimprefix("# ") | "abc # 123" |
trimstart | remove leading whitespace in a string |
" abc".trimstart | "abc" |
trimsuffix | remove ending substring, if present |
"text line\r".trimsuffix("\r") | "text line" |
"text line".trimsuffix("\r") | "text line" |
trunc, truncate | truncate, or round closer to 0 |
-19.9.trunc | -19 |
19.9.trunc | 19 |
tstype | get any value's TypeScript type |
null.tstype | "null" |
false.tstype | "boolean" |
3.5.tstype | "number" |
"".tstype | "string" |
a().tstype | "any[]" |
a(1, 2, 3).tstype | "number[]" |
a(-5.3, "abc").tstype | "(number | string)[]" |
_{a: 1, b: "abc"}.tstype() | "interface {\n \"a\": number\n \"b\": string\n}" |
typeof | get any value's type |
null.typeof | "null" |
false.typeof | "boolean" |
3.typeof | "number" |
"".typeof | "string" |
a().typeof | "array" |
_{}.typeof | "object" |
y0 | 0th-order bessel y function |
y1 | 1st-order bessel y function |
yn(n, x) | nth-order bessel y function |
ymd2d | parse a date string and get the day as a number |
"2020-05-16".ymd2d | 16 |
"2020/05/16".ymd2d | 16 |
ymd2m | parse a date string and get the month as a number |
"2020-05-16".ymd2m | 5 |
"2020/05/16".ymd2m | 5 |
ymd2y | parse a date string and get the year as a number |
"2020-05-16".ymd2y | 2,020 |
"2020/05/16".ymd2y | 2,020 |
all, every | do all values satisfy the formula? |
a(1, 2, 3, 4, 5) . all(v % 2 == 0) | false |
any, some | do any values satisfy the formula? |
a(1, 2, 3, 4, 5) . any(v % 2 == 0) | true |
assert, must | ensure a (pre)condition holds |
assert(123.type == "number") | null |
assert(123.type == "number", "not a number") | null |
call | call a function by name |
"c".call("hi", 123) | ["hi", 123] |
count, countif | count how many values satisfy the formula |
a(1, 2, 3, 4, 5) . countif(v % 2 == 0) | 2 |
dive | like each, but transforms basic values depth-first recursively, keeping the same general nested shape of the input |
a(1, 2, 3, 4, 5) . dive(v % 2) | [1, 0, 1, 0, 1] |
each | transform values according to the formula |
a(1, 2, 3, 4, 5) . each(v % 2) | [1, 0, 1, 0, 1] |
a(1, 2, 3, 4, 5) . each(v % 2 == 0) | [false, true, false, true, false] |
eval | evaluate GoTron source code |
"5.each(v) . pow2".eval | [2, 4, 8, 16, 32] |
filter, only | keep only the values satisfying the formula |
a(1, 2, 3, 4, 5) . filter(v % 2 == 0) | [2, 4] |
fn, lambda | make an anonymous function |
group, groupby | split array/object by formula |
a(1, 2, 3, 4, 5) . group(v % 2) | {"1"; [1, 3, 5], "0": [2, 4]} |
order, orderby, sort | sort array/object using multiple criteria |
a("abc", "xyz", "def").sort | [3.4, "abc", "def"] |
a("abc", "xyz", "def").sort | ["abc", "def", "xyz"] |
a("abc", "xyz", "def").sort(v.len, -v) | ["xyz", "def", "abc"] |
a("abc", "xyz", "def").sort(-v) | ["xyz", "def", "abc"] |
a("abc", "xyz", "def").sort | ["abc", "def", "xyz"] |
rekey | rename all object keys recursively |
monthlen.rekey(k.lower[:3]).keys() | ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"] |
ren, rename | rename an object |
_{a: 123, b: 456}.rename(k + v) | {"a123": 123, "b456": 456} |
_{a: 123, b: 456}.rename(_{a: `xyz`}) | {"xyz": 123, "b": 456} |
surgery | recursively transform values of matching object keys |
tally | make a tally (count) of each distinct result the formula gives |
a(1, 2, 3, 4, 5) . tally(v % 2) | {"1"; 3, "0": 2} |
Some of these examples are for `jf` (Jeff), instead of `gt` (GoTron).
Wondering how long float64 mantissas will work as unix-style timestamps... are those in millionths or billionths of a second?
gt '2i.pow(_{52,53,64})/_{1e6,1e9}/day/365.25+1970' .
A partial ASCII table.
gt '(space + visascii).each(v, v.ord)' .
Calculate how long do 4GB of PCM-audio (.wav files) last, under various settings.
gt '// 16-bit/2-byte samples, mono or stereo, for both CD-audio and DAT _{44_100, 48_000, 96_000} * _{mono: 1, stereo: 2} * 2 & // find how many seconds 4 GB last with those settings, playback-wise (4 * gb) / _ & // turn seconds into HH:MM:SS.SS-style strings _ . dive(a(floor(v / 3600), floor(v % 3600 / 60), fix(v % 60, 2)) ^ `:`) ' .
Another way to do it.
gt '// bytes/sec (4 * gb) / (_{44_100, 48_000, 96_000} * _{mono: 1, stereo: 2} * 2) & // sec to HH:MM:SS.SS _ . dive(a(floor(v / hr), floor(v % hr / 60), fix(v % 60, 2)) ^ `:`) & // use fancier top-level labels _ . each(k + ` hz`, v) ' .
Same as above, but using a more general formula.
jf -from=n '{`${64*v}k`: 8*v: 2..4} * {v.fix1: v: .5*20.iota} * 60'
You say ... about 1500 each day, what range is that a year?
jf -from=n 1500.fuzz*[365,366].kv
Now you tell me it's about 1400-1500 a day, so I guess you meant to say between 1400 and 1500 a day, which makes the yearly ranges...
gt '^a(1400, 1500) * ^a(365, 366)' .
Approximate e using its truncated-series expansions.
gt '_{ e: e, approx: define(a, 0) & (0 ^ 20).each(v, define(a, a + 1 / gamma(v + 1)) & a), }' .
Get date/time-related info for your timezone.
gt . https://worldtimeapi.org/api/ip
Get date/time-related info for your timezone, then ignore info about your own IP address, so it doesn't show in the result.
gt 'data.drop(`client_ip`)' https://worldtimeapi.org/api/ip
A quick way to view a few integer base-10 logarithms.
gt '10i.each(v, v.log10.fix2)' .
A complete shell function to REPeat the text given.
rep() { jf -from=null "repeat('${1:--}', ${2:-80}, '${3:-}')"; }
Reshape headlines/data from live reuters feed.
gt 'data.rss.channel[0].item . each(_{ title: v.title, link: v.link, when: v.pubDate })' \ "https://news.google.com/rss/search?q=when:12h+allinurl:reuters.com&ceid=US:en&hl=en-US&gl=US"
Get URI for JSON exchange rates from the Bank of Canada, since the start of the month: using shell substitution effectively prevents using the string-interpolation syntax, which would interfere with the shell's own substitution syntax.
echo https://www.bankofcanada.ca/valet/observations/group/FX_RATES_DAILY/json?\ start_date=`gt 'now.year + "-" + now.month + "-01"' .`
Get recent `live` exchange rates from the Bank of Canada, and transform values from the latest record. The shell-injected use of the current year is to get a URI for data since the beginning of the current year: this avoids downloading data for several years, thus speeding up things.
gt 'define( latest, data.observations[-1], rates, latest.drop(`d`).each(k - `FX` - `CAD`, +v.v), ) & merge(_{ date: latest.d }, rates.sort(k))' \ https://www.bankofcanada.ca/valet/observations/group/FX_RATES_DAILY/json?start_date=`date +%Y`-01-01
Calculate the first 80 fibonacci numbers, since float64 values start giving wrong results at around 80 items.
echo 80 | gt 'define(a, 1, b, 0) & data.each(v, define(b, a + b, a, b) & b)'
Calculate prime numbers using the algorithm with O(n**1.5) time-complexity.
echo 100 | gt 'data . only(define(n, v) & n != 1 && n.sqrt.all(define(div, v) & (div == 1 || n % div != 0))) . each((k + 1) + denil(a(`st`, `nd`, `rd`)[k % 10], `th`), v)'
excel | closest gt | concise gt |
---|---|---|
=CHAR(n) | =char(n) | n.char, n.rune |
=LOWER(s) | =lower(s) | s.lower |
=UPPER(s) | =upper(s) | s.upper |
=TEXTBEFORE(s, t) | =textbefore(s, t) | s.textbefore(t) |
=TEXTAFTER(s, t) | =textafter(s, t) | s.textafter(t) |
SQL | closest gt | concise gt |
---|---|---|
select * from v order by x | v.orderby(x) | v.sort(x) |
select * from v order by x asc, y desc | v.orderby(x, -y) | v.sort(x, -y) |
printf("%s ...", x) | x.str + ... | `${x} ...` |
javascript | closest gt | concise gt |
---|---|---|
null | null | nil |
true | true | true |
false | false | false |
Math.E | e | e |
Math.PI | pi | pi |
NaN | nan | nan |
Infinity | infinity | inf |
isNaN(n) | isnan(n) | n.isnan |
isFinite(n) | isfinite(n) | n.isinf.not |
!isFinite(n) | !isfinite(n) | n.isinf |
+s | +s | +s |
a.reduce((x, y) => x + y) | a.reduce(x + y) | a.sum |
a.reduce((x, y) => x * y) | a.reduce(x * y) | a.prod |
Math.sin(n) | sin(n) | n.sin |
x.toString() | x.tostring() | x.str() |
s.toLowerCase() | s.tolowercase(), s.tolowercase | s.lower |
s.toUpperCase() | s.touppercase(), s.touppercase | s.upper |
s.replaceAll(t, "") | s.replaceall(t, ""), s.replace(t, "") | s - t |
s.replaceAll(t, u) | s.replaceall(t, u), s.replace(t, u) | s / t ^ u |
a.join(s) | a.join(s), s.join(a) | a ^ s, s ^ a |
s.split(t) | s.split(t) | s / t |
s.split("") | s.split("") | s.chars, s.runes, ^s, s / "" |
String.fromCharCode(n) | fromcharcode(n), chr(n) | n.char, n.rune, n.chr |
n.toString(2) | n.tostring(2) | n.bin |
n.toString(8) | n.tostring(8) | n.oct |
n.toString(16) | n.tostring(16) | n.hex |
JSON.stringify(x) | stringify(x) | x.json() |
JSON.parse(s) | parse(s) | s.parse |
a.length | a.length | a.len |
Object.keys(o) | keys(o) | o.keys() |
Object.values(o) | values(o) | ^o |
c = 0; for (e of s) { c++ }; c | s.count(true) | s.len |
a.map((v, k) => [k, v]) | a.map((v, k) => [k, v]) | a.map((k, v)) |
a[a.length - 2] | a[a.length - 2] | a[-2] |
a.slice(0, Math.min(a.length, 8)) | a.slice(0, min(a.length, 8)) | a[:9], a.first9 |
a.slice(0, Math.min(a.length, 19)) | a.slice(0, min(a.length, 19)) | a[:20], a.first(20) |
s.repeat(n) | s.repeat(n) | s * n |
a.map(x => 125 * x) | a.map(x => 125 * x) | 125 * a |
+s | +s | +s |
python | closest gt | concise gt |
---|---|---|
None | none | nil |
True | true | true |
False | false | false |
math.e | e | e |
math.pi | pi | pi |
math.tau | tau | tau |
math.nan | nan | nan |
math.inf | inf | inf |
string.whitespace | whitespace | whitespace |
string.punctuation | punctuation | punctuation |
string.digits | digits | digits |
string.hexdigits | hexdigits | hexdigits |
string.ascii_lowercase | lowercase | lower |
string.ascii_uppercase | uppercase | upper |
string.ascii_letters | letters | letters |
math.isnan(n) | isnan(n) | n.isnan |
math.isinf(n) | isinf(n) | n.isinf |
float(s) | float(s) | +s |
sum(a) | sum(a) | a.sum |
prod(a) | prod(a) | a.prod |
math.sin(n) | sin(n) | n.sin |
str(x) | str(x) | str(x) |
tolower(s) | tolower(s) | s.lower |
toupper(s) | toupper(s) | s.upper |
s.replace(t, "") | s.replace(t, "") | s - t |
s.replace(t, u) | s.replace(t, u) | s / t ^ u |
s.join((str(e) for e in a)) | s.join(a), a.join(s) | s ^ a, a ^ s |
s.split(t) | s.split(t) | s / t |
[e**2 for e in a] | a.pow(2) | a.pow2() |
[e for e in s] | s.each(v) | s.chars, s.runes, s / "" |
[tolower(e) for e in a] | aeach(tolower(v)) | a.lower |
[[log2(f) for f in e] for e in a] | [e => [f => log2(f): e]: a] | a.log2 |
ord(s) | ord(s) | s.ord |
bin(n) | bin(n) | n.bin |
hex(n) | hex(n) | n.hex |
json.dumps(x) | dumps(x) | x.json() |
json.loads(s) | loads(s) | s.loads, s.parse |
len(s) | len(s) | s.len |
len(a) | len(a) | a.len |
list(o.keys()) | o.keys() | o.keys() |
list(o.values()) | o.values() | ^o |
list(enumerate(a)) | a.each(i, v) | a.each(i, v) |
list(range(n)) | indices(n), indexes(n) | *n |
list(range(1, n+1)) | seq(1, n) | n.each(v), 1^n |
list(range(m, n+1)) | m^n | m^n |
a[-2] | a[-2] | a[-2] |
a[:min(len(a), 9)] | a[:min(len(a), 9)] | a[:9], a.first9 |
a[:min(len(a), 20)] | a[:min(len(a), 20)] | a[:20], a.first(20) |
25 * s | 25 * s | 25 * s |
[125 * e for e in a] | a.each(125 * v) | 125 * a |
A recent run of the following command results in the table below.
jf -from=null -to=html 'funcs().toentries().map({name: v[0], type: v[1]})'
name | type |
---|---|
name | type |
Before showing most variables, here are some special-use variables.
name | type | uses |
---|
The following (shell) script created the table shown right after.
#!/bin/sh
name | value |
---|---|
name | value |