New fmtifnum DSL function; make fmtnum/fmtifnum recursive over maps and arrays (#946)

* New fmtifnum DSL function

* doc-build artifacts for previous commit

* Make fmtnum/fmtifnum recursive over maps and arrays

* Online-help examples for fmtnum/fmtifnum

* doc-build artifacts for previous commit

* unit-test cases

* code-dedupe
This commit is contained in:
John Kerl 2022-02-14 23:57:14 -05:00 committed by GitHub
parent f7dd3d284e
commit bb95f37066
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 344 additions and 34 deletions

View file

@ -206,11 +206,11 @@ FUNCTION LIST
asserting_not_map asserting_not_null asserting_null asserting_numeric
asserting_present asserting_string atan atan2 atanh bitcount boolean
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtnum
fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime gmt2sec gsub
haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent is_array
is_bool is_boolean is_empty is_empty_map is_error is_float is_int is_map
is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtifnum
fmtnum fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime
gmt2sec gsub haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent
is_array is_bool is_boolean is_empty is_empty_map is_error is_float is_int
is_map is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
is_null is_numeric is_present is_string joink joinkv joinv json_parse
json_stringify leafcount length localtime2gmt localtime2sec log log10 log1p
logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min mmul
@ -2189,8 +2189,15 @@ FUNCTIONS FOR FILTER/PUT
floor
(class=math #args=1) Floor: nearest integer at or below.
fmtifnum
(class=conversion #args=2) Identical to fmtnum, except returns the first argument as-is if the output would be an error.
Example:
$* = fmtifnum($*, "%.6f")
fmtnum
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'.
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'. This function recurses on array and map values.
Example:
$x = fmtifnum($x, "%.6f")
fold
(class=higher-order-functions #args=3) Given a map or array as first argument and a function as second argument, accumulates entries into a final output -- for example, sum or product. For arrays, the function should take two arguments, for accumulated value and array element. For maps, it should take four arguments, for accumulated key and value, and map-element key and value; it should return the updated accumulator as a new key-value pair (i.e. a single-entry map). The start value for the accumulator is taken from the third argument.
@ -3174,5 +3181,5 @@ SEE ALSO
2022-02-08 MILLER(1)
2022-02-15 MILLER(1)
</pre>

View file

@ -185,11 +185,11 @@ FUNCTION LIST
asserting_not_map asserting_not_null asserting_null asserting_numeric
asserting_present asserting_string atan atan2 atanh bitcount boolean
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtnum
fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime gmt2sec gsub
haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent is_array
is_bool is_boolean is_empty is_empty_map is_error is_float is_int is_map
is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtifnum
fmtnum fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime
gmt2sec gsub haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent
is_array is_bool is_boolean is_empty is_empty_map is_error is_float is_int
is_map is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
is_null is_numeric is_present is_string joink joinkv joinv json_parse
json_stringify leafcount length localtime2gmt localtime2sec log log10 log1p
logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min mmul
@ -2168,8 +2168,15 @@ FUNCTIONS FOR FILTER/PUT
floor
(class=math #args=1) Floor: nearest integer at or below.
fmtifnum
(class=conversion #args=2) Identical to fmtnum, except returns the first argument as-is if the output would be an error.
Example:
$* = fmtifnum($*, "%.6f")
fmtnum
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'.
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'. This function recurses on array and map values.
Example:
$x = fmtifnum($x, "%.6f")
fold
(class=higher-order-functions #args=3) Given a map or array as first argument and a function as second argument, accumulates entries into a final output -- for example, sum or product. For arrays, the function should take two arguments, for accumulated value and array element. For maps, it should take four arguments, for accumulated key and value, and map-element key and value; it should return the updated accumulator as a new key-value pair (i.e. a single-entry map). The start value for the accumulator is taken from the third argument.
@ -3153,4 +3160,4 @@ SEE ALSO
2022-02-08 MILLER(1)
2022-02-15 MILLER(1)

View file

@ -70,7 +70,7 @@ is 2. Unary operators such as `!` and `~` show argument-count of 1; the ternary
* [**Arithmetic functions**](#arithmetic-functions): [bitcount](#bitcount), [madd](#madd), [mexp](#mexp), [mmul](#mmul), [msub](#msub), [pow](#pow), [%](#percent), [&](#bitwise-and), [\*](#times), [\**](#exponentiation), [\+](#plus), [\-](#minus), [\.\*](#dot-times), [\.\+](#dot-plus), [\.\-](#dot-minus), [\./](#dot-slash), [/](#slash), [//](#slash-slash), [<<](#lsh), [>>](#srsh), [>>>](#ursh), [^](#bitwise-xor), [\|](#bitwise-or), [~](#bitwise-not).
* [**Boolean functions**](#boolean-functions): [\!](#exclamation-point), [\!=](#exclamation-point-equals), [!=~](#regnotmatch), [&&](#logical-and), [<](#less-than), [<=](#less-than-or-equals), [<=>](#<=>), [==](#double-equals), [=~](#regmatch), [>](#greater-than), [>=](#greater-than-or-equals), [?:](#question-mark-colon), [??](#absent-coalesce), [???](#absent-empty-coalesce), [^^](#logical-xor), [\|\|](#logical-or).
* [**Collections functions**](#collections-functions): [append](#append), [arrayify](#arrayify), [concat](#concat), [depth](#depth), [flatten](#flatten), [get_keys](#get_keys), [get_values](#get_values), [haskey](#haskey), [json_parse](#json_parse), [json_stringify](#json_stringify), [leafcount](#leafcount), [length](#length), [mapdiff](#mapdiff), [mapexcept](#mapexcept), [mapselect](#mapselect), [mapsum](#mapsum), [unflatten](#unflatten).
* [**Conversion functions**](#conversion-functions): [boolean](#boolean), [float](#float), [fmtnum](#fmtnum), [hexfmt](#hexfmt), [int](#int), [joink](#joink), [joinkv](#joinkv), [joinv](#joinv), [splita](#splita), [splitax](#splitax), [splitkv](#splitkv), [splitkvx](#splitkvx), [splitnv](#splitnv), [splitnvx](#splitnvx), [string](#string).
* [**Conversion functions**](#conversion-functions): [boolean](#boolean), [float](#float), [fmtifnum](#fmtifnum), [fmtnum](#fmtnum), [hexfmt](#hexfmt), [int](#int), [joink](#joink), [joinkv](#joinkv), [joinv](#joinv), [splita](#splita), [splitax](#splitax), [splitkv](#splitkv), [splitkvx](#splitkvx), [splitnv](#splitnv), [splitnvx](#splitnvx), [string](#string).
* [**Hashing functions**](#hashing-functions): [md5](#md5), [sha1](#sha1), [sha256](#sha256), [sha512](#sha512).
* [**Higher-order-functions functions**](#higher-order-functions-functions): [any](#any), [apply](#apply), [every](#every), [fold](#fold), [reduce](#reduce), [select](#select), [sort](#sort).
* [**Math functions**](#math-functions): [abs](#abs), [acos](#acos), [acosh](#acosh), [asin](#asin), [asinh](#asinh), [atan](#atan), [atan2](#atan2), [atanh](#atanh), [cbrt](#cbrt), [ceil](#ceil), [cos](#cos), [cosh](#cosh), [erf](#erf), [erfc](#erfc), [exp](#exp), [expm1](#expm1), [floor](#floor), [invqnorm](#invqnorm), [log](#log), [log10](#log10), [log1p](#log1p), [logifit](#logifit), [max](#max), [min](#min), [qnorm](#qnorm), [round](#round), [roundm](#roundm), [sgn](#sgn), [sin](#sin), [sinh](#sinh), [sqrt](#sqrt), [tan](#tan), [tanh](#tanh), [urand](#urand), [urand32](#urand32), [urandelement](#urandelement), [urandint](#urandint), [urandrange](#urandrange).
@ -488,9 +488,19 @@ float (class=conversion #args=1) Convert int/float/bool/string to float.
</pre>
### fmtifnum
<pre class="pre-non-highlight-non-pair">
fmtifnum (class=conversion #args=2) Identical to fmtnum, except returns the first argument as-is if the output would be an error.
Example:
$* = fmtifnum($*, "%.6f")
</pre>
### fmtnum
<pre class="pre-non-highlight-non-pair">
fmtnum (class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'.
fmtnum (class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'. This function recurses on array and map values.
Example:
$x = fmtifnum($x, "%.6f")
</pre>

View file

@ -48,6 +48,7 @@
package bifs
import (
"github.com/johnkerl/miller/internal/pkg/lib"
"github.com/johnkerl/miller/internal/pkg/mlrval"
"github.com/johnkerl/miller/internal/pkg/types"
)
@ -200,3 +201,27 @@ func _same(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
func _more(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return mlrval.FromInt(1)
}
// recuriseBinaryFuncOnInput1 is for fmtifnum and other functions which apply themselves recursively
// on array/map inputs.
func recuriseBinaryFuncOnInput1(binaryFunc BinaryFunc, input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsArray() {
inputArray := input1.GetArray()
lib.InternalCodingErrorIf(inputArray == nil)
outputArray := make([]*mlrval.Mlrval, len(inputArray))
for i := range inputArray {
outputArray[i] = binaryFunc(inputArray[i], input2)
}
return mlrval.FromArray(outputArray)
} else if input1.IsMap() {
inputMap := input1.GetMap()
lib.InternalCodingErrorIf(inputMap == nil)
outputMap := mlrval.NewMlrmap()
for pe := inputMap.Head; pe != nil; pe = pe.Next {
outputMap.PutReference(pe.Key, binaryFunc(pe.Value, input2))
}
return mlrval.FromMap(outputMap)
} else {
return fmtnum_dispositions[input1.Type()][input2.Type()](input1, input2)
}
}

View file

@ -463,5 +463,22 @@ var fmtnum_dispositions = [mlrval.MT_DIM][mlrval.MT_DIM]BinaryFunc{
}
func BIF_fmtnum(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
return fmtnum_dispositions[input1.Type()][input2.Type()](input1, input2)
if input1.IsArray() || input1.IsMap() {
return recuriseBinaryFuncOnInput1(BIF_fmtnum, input1, input2)
} else {
return fmtnum_dispositions[input1.Type()][input2.Type()](input1, input2)
}
}
func BIF_fmtifnum(input1, input2 *mlrval.Mlrval) *mlrval.Mlrval {
if input1.IsArray() || input1.IsMap() {
return recuriseBinaryFuncOnInput1(BIF_fmtifnum, input1, input2)
} else {
output := fmtnum_dispositions[input1.Type()][input2.Type()](input1, input2)
if output.IsError() {
return input1
} else {
return output
}
}
}

View file

@ -1446,8 +1446,21 @@ Note that NaN has the property that NaN != NaN, so you need 'is_nan(x)' rather t
name: "fmtnum",
class: FUNC_CLASS_CONVERSION,
help: `Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g.
'$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'.`,
'$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'. This function recurses on array and map values.`,
binaryFunc: bifs.BIF_fmtnum,
examples: []string{
`$x = fmtifnum($x, "%.6f")`,
},
},
{
name: "fmtifnum",
class: FUNC_CLASS_CONVERSION,
help: `Identical to fmtnum, except returns the first argument as-is if the output would be an error.`,
binaryFunc: bifs.BIF_fmtifnum,
examples: []string{
`$* = fmtifnum($*, "%.6f")`,
},
},
{

View file

@ -185,11 +185,11 @@ FUNCTION LIST
asserting_not_map asserting_not_null asserting_null asserting_numeric
asserting_present asserting_string atan atan2 atanh bitcount boolean
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtnum
fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime gmt2sec gsub
haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent is_array
is_bool is_boolean is_empty is_empty_map is_error is_float is_int is_map
is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtifnum
fmtnum fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime
gmt2sec gsub haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent
is_array is_bool is_boolean is_empty is_empty_map is_error is_float is_int
is_map is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
is_null is_numeric is_present is_string joink joinkv joinv json_parse
json_stringify leafcount length localtime2gmt localtime2sec log log10 log1p
logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min mmul
@ -2168,8 +2168,15 @@ FUNCTIONS FOR FILTER/PUT
floor
(class=math #args=1) Floor: nearest integer at or below.
fmtifnum
(class=conversion #args=2) Identical to fmtnum, except returns the first argument as-is if the output would be an error.
Example:
$* = fmtifnum($*, "%.6f")
fmtnum
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'.
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'. This function recurses on array and map values.
Example:
$x = fmtifnum($x, "%.6f")
fold
(class=higher-order-functions #args=3) Given a map or array as first argument and a function as second argument, accumulates entries into a final output -- for example, sum or product. For arrays, the function should take two arguments, for accumulated value and array element. For maps, it should take four arguments, for accumulated key and value, and map-element key and value; it should return the updated accumulator as a new key-value pair (i.e. a single-entry map). The start value for the accumulator is taken from the third argument.
@ -3153,4 +3160,4 @@ SEE ALSO
2022-02-08 MILLER(1)
2022-02-15 MILLER(1)

View file

@ -2,12 +2,12 @@
.\" Title: mlr
.\" Author: [see the "AUTHOR" section]
.\" Generator: ./mkman.rb
.\" Date: 2022-02-08
.\" Date: 2022-02-15
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "MILLER" "1" "2022-02-08" "\ \&" "\ \&"
.TH "MILLER" "1" "2022-02-15" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Portability definitions
.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -232,11 +232,11 @@ asserting_map asserting_nonempty_map asserting_not_array asserting_not_empty
asserting_not_map asserting_not_null asserting_null asserting_numeric
asserting_present asserting_string atan atan2 atanh bitcount boolean
capitalize cbrt ceil clean_whitespace collapse_whitespace concat cos cosh
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtnum
fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime gmt2sec gsub
haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent is_array
is_bool is_boolean is_empty is_empty_map is_error is_float is_int is_map
is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
depth dhms2fsec dhms2sec erf erfc every exp expm1 flatten float floor fmtifnum
fmtnum fold format fsec2dhms fsec2hms get_keys get_values gmt2localtime
gmt2sec gsub haskey hexfmt hms2fsec hms2sec hostname int invqnorm is_absent
is_array is_bool is_boolean is_empty is_empty_map is_error is_float is_int
is_map is_nan is_nonempty_map is_not_array is_not_empty is_not_map is_not_null
is_null is_numeric is_present is_string joink joinkv joinv json_parse
json_stringify leafcount length localtime2gmt localtime2sec log log10 log1p
logifit lstrip madd mapdiff mapexcept mapselect mapsum max md5 mexp min mmul
@ -3007,12 +3007,25 @@ flatten("", ".", {"a": { "b": 3 }}) is {"a.b" : 3}.
.fi
.if n \{\
.RE
.SS "fmtifnum"
.if n \{\
.RS 0
.\}
.nf
(class=conversion #args=2) Identical to fmtnum, except returns the first argument as-is if the output would be an error.
Example:
$* = fmtifnum($*, "%.6f")
.fi
.if n \{\
.RE
.SS "fmtnum"
.if n \{\
.RS 0
.\}
.nf
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'.
(class=conversion #args=2) Convert int/float/bool to string using printf-style format string (https://pkg.go.dev/fmt), e.g. '$s = fmtnum($n, "%08d")' or '$t = fmtnum($n, "%.6e")'. This function recurses on array and map values.
Example:
$x = fmtifnum($x, "%.6f")
.fi
.if n \{\
.RE

View file

@ -0,0 +1 @@
mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr

View file

@ -0,0 +1,11 @@
a b i x y
(error) pan 1 3.468e-01 0.7268028627434533
(error) pan 2 7.587e-01 -0.5221511083334797
(error) wye 3 2.046e-01 0.33831852551664776
(error) wye 4 3.814e-01 -0.13418874328430463
(error) pan 5 5.733e-01 0.8636244699032729
(error) pan 6 5.271e-01 -0.49322128674835697
(error) zee 7 6.118e-01 0.1878849191181694
(error) wye 8 5.986e-01 0.976181385699006
(error) wye 9 3.144e-02 -0.7495507603507059
(error) wye 10 5.026e-01 0.9526183602969864

View file

@ -0,0 +1,3 @@
$a = fmtnum($a, "%8.3e");
$x = fmtnum($x, "%8.3e");

View file

@ -0,0 +1 @@
mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr

View file

@ -0,0 +1,11 @@
a b i x y
pan pan 1 3.468e-01 0.7268028627434533
eks pan 2 7.587e-01 -0.5221511083334797
wye wye 3 2.046e-01 0.33831852551664776
eks wye 4 3.814e-01 -0.13418874328430463
wye pan 5 5.733e-01 0.8636244699032729
zee pan 6 5.271e-01 -0.49322128674835697
eks zee 7 6.118e-01 0.1878849191181694
zee wye 8 5.986e-01 0.976181385699006
hat wye 9 3.144e-02 -0.7495507603507059
pan wye 10 5.026e-01 0.9526183602969864

View file

@ -0,0 +1,3 @@
$a = fmtifnum($a, "%8.3e");
$x = fmtifnum($x, "%8.3e");

View file

@ -0,0 +1 @@
mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr

View file

@ -0,0 +1,11 @@
a b i x y
(error) (error) 1.000e+00 3.468e-01 7.268e-01
(error) (error) 2.000e+00 7.587e-01 -5.222e-01
(error) (error) 3.000e+00 2.046e-01 3.383e-01
(error) (error) 4.000e+00 3.814e-01 -1.342e-01
(error) (error) 5.000e+00 5.733e-01 8.636e-01
(error) (error) 6.000e+00 5.271e-01 -4.932e-01
(error) (error) 7.000e+00 6.118e-01 1.879e-01
(error) (error) 8.000e+00 5.986e-01 9.762e-01
(error) (error) 9.000e+00 3.144e-02 -7.496e-01
(error) (error) 1.000e+01 5.026e-01 9.526e-01

View file

@ -0,0 +1 @@
$* = fmtnum($*, "%8.3e");

View file

@ -0,0 +1 @@
mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr

View file

@ -0,0 +1,11 @@
a b i x y
pan pan 1.000e+00 3.468e-01 7.268e-01
eks pan 2.000e+00 7.587e-01 -5.222e-01
wye wye 3.000e+00 2.046e-01 3.383e-01
eks wye 4.000e+00 3.814e-01 -1.342e-01
wye pan 5.000e+00 5.733e-01 8.636e-01
zee pan 6.000e+00 5.271e-01 -4.932e-01
eks zee 7.000e+00 6.118e-01 1.879e-01
zee wye 8.000e+00 5.986e-01 9.762e-01
hat wye 9.000e+00 3.144e-02 -7.496e-01
pan wye 1.000e+01 5.026e-01 9.526e-01

View file

@ -0,0 +1 @@
$* = fmtifnum($*, "%8.3e");

View file

@ -0,0 +1 @@
mlr --ojson --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr

View file

@ -0,0 +1,142 @@
[
{
"a": "pan",
"b": "pan",
"i": 1,
"x": 0.3467901443380824,
"y": 0.7268028627434533,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "eks",
"b": "pan",
"i": 2,
"x": 0.7586799647899636,
"y": -0.5221511083334797,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "wye",
"b": "wye",
"i": 3,
"x": 0.20460330576630303,
"y": 0.33831852551664776,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "eks",
"b": "wye",
"i": 4,
"x": 0.38139939387114097,
"y": -0.13418874328430463,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "wye",
"b": "pan",
"i": 5,
"x": 0.5732889198020006,
"y": 0.8636244699032729,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "zee",
"b": "pan",
"i": 6,
"x": 0.5271261600918548,
"y": -0.49322128674835697,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "eks",
"b": "zee",
"i": 7,
"x": 0.6117840605678454,
"y": 0.1878849191181694,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "zee",
"b": "wye",
"i": 8,
"x": 0.5985540091064224,
"y": 0.976181385699006,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "hat",
"b": "wye",
"i": 9,
"x": 0.03144187646093577,
"y": -0.7495507603507059,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
},
{
"a": "pan",
"b": "wye",
"i": 10,
"x": 0.5026260055412137,
"y": 0.9526183602969864,
"mymap": {
"a": [2.000e+00, 3.400e+00, "e"],
"f": {
"g": [8.000e+00, 9.100e+00],
"h": 1.100e+01
}
}
}
]

View file

@ -0,0 +1,5 @@
mymap = {
"a": [2,3.4,"e"],
"f": {"g": [8, 9.1], "h": 11},
};
$mymap = fmtifnum(mymap, "%8.3e");

View file

@ -1,5 +1,4 @@
=============================================================== RELEASES
* plan 6.1.0
? strptime/882
m strptime/strftime tabulate options
@ -8,6 +7,14 @@
? port mlr5 c -> go?
? unsparsify -f CSV by default -- ? into CSV record-writer -- ? caveat that record 1 controls all ...
? mlr join --left-fields a,b,c
o fmtifnum, & recursive fmtnum/fmtifnum
k fmtifnum olh artifacts
k both: array/map code
k both: array/map olh artifacts
- fmtifnum UT cases
- both: array/map UT cases
- after UT: try a closure/curry on input2
- hexfmt also recursive
o fmt/unfmt/regex doc
o FAQ/examples reorg
k unicode string literals