diff --git a/docs/src/manpage.md b/docs/src/manpage.md index ea40bc25a..ca5f2bb5b 100644 --- a/docs/src/manpage.md +++ b/docs/src/manpage.md @@ -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) diff --git a/docs/src/manpage.txt b/docs/src/manpage.txt index 5eb17b369..8518f0fa7 100644 --- a/docs/src/manpage.txt +++ b/docs/src/manpage.txt @@ -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) diff --git a/docs/src/reference-dsl-builtin-functions.md b/docs/src/reference-dsl-builtin-functions.md index 4fe0cf373..450a266ed 100644 --- a/docs/src/reference-dsl-builtin-functions.md +++ b/docs/src/reference-dsl-builtin-functions.md @@ -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. +### fmtifnum +
+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
-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")diff --git a/internal/pkg/bifs/base.go b/internal/pkg/bifs/base.go index 914edf950..500a84103 100644 --- a/internal/pkg/bifs/base.go +++ b/internal/pkg/bifs/base.go @@ -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) + } +} diff --git a/internal/pkg/bifs/strings.go b/internal/pkg/bifs/strings.go index e11a3b1ed..fdd56d162 100644 --- a/internal/pkg/bifs/strings.go +++ b/internal/pkg/bifs/strings.go @@ -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 + } + } } diff --git a/internal/pkg/dsl/cst/builtin_function_manager.go b/internal/pkg/dsl/cst/builtin_function_manager.go index 47add2557..08650fa0e 100644 --- a/internal/pkg/dsl/cst/builtin_function_manager.go +++ b/internal/pkg/dsl/cst/builtin_function_manager.go @@ -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")`, + }, }, { diff --git a/man/manpage.txt b/man/manpage.txt index 5eb17b369..8518f0fa7 100644 --- a/man/manpage.txt +++ b/man/manpage.txt @@ -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) diff --git a/man/mlr.1 b/man/mlr.1 index b6ed60bfb..4eed1c176 100644 --- a/man/mlr.1 +++ b/man/mlr.1 @@ -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 diff --git a/test/cases/dsl-number-formatting/0003/cmd b/test/cases/dsl-number-formatting/0003/cmd new file mode 100644 index 000000000..1c7544377 --- /dev/null +++ b/test/cases/dsl-number-formatting/0003/cmd @@ -0,0 +1 @@ +mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr diff --git a/test/cases/dsl-number-formatting/0003/experr b/test/cases/dsl-number-formatting/0003/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-number-formatting/0003/expout b/test/cases/dsl-number-formatting/0003/expout new file mode 100644 index 000000000..487cf0bd0 --- /dev/null +++ b/test/cases/dsl-number-formatting/0003/expout @@ -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 diff --git a/test/cases/dsl-number-formatting/0003/mlr b/test/cases/dsl-number-formatting/0003/mlr new file mode 100644 index 000000000..2b06eb236 --- /dev/null +++ b/test/cases/dsl-number-formatting/0003/mlr @@ -0,0 +1,3 @@ +$a = fmtnum($a, "%8.3e"); +$x = fmtnum($x, "%8.3e"); + diff --git a/test/cases/dsl-number-formatting/0004/cmd b/test/cases/dsl-number-formatting/0004/cmd new file mode 100644 index 000000000..1c7544377 --- /dev/null +++ b/test/cases/dsl-number-formatting/0004/cmd @@ -0,0 +1 @@ +mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr diff --git a/test/cases/dsl-number-formatting/0004/experr b/test/cases/dsl-number-formatting/0004/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-number-formatting/0004/expout b/test/cases/dsl-number-formatting/0004/expout new file mode 100644 index 000000000..5f3e17f3f --- /dev/null +++ b/test/cases/dsl-number-formatting/0004/expout @@ -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 diff --git a/test/cases/dsl-number-formatting/0004/mlr b/test/cases/dsl-number-formatting/0004/mlr new file mode 100644 index 000000000..c032dc57b --- /dev/null +++ b/test/cases/dsl-number-formatting/0004/mlr @@ -0,0 +1,3 @@ +$a = fmtifnum($a, "%8.3e"); +$x = fmtifnum($x, "%8.3e"); + diff --git a/test/cases/dsl-number-formatting/0005/cmd b/test/cases/dsl-number-formatting/0005/cmd new file mode 100644 index 000000000..1c7544377 --- /dev/null +++ b/test/cases/dsl-number-formatting/0005/cmd @@ -0,0 +1 @@ +mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr diff --git a/test/cases/dsl-number-formatting/0005/experr b/test/cases/dsl-number-formatting/0005/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-number-formatting/0005/expout b/test/cases/dsl-number-formatting/0005/expout new file mode 100644 index 000000000..00ff52cc7 --- /dev/null +++ b/test/cases/dsl-number-formatting/0005/expout @@ -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 diff --git a/test/cases/dsl-number-formatting/0005/mlr b/test/cases/dsl-number-formatting/0005/mlr new file mode 100644 index 000000000..2800ba82f --- /dev/null +++ b/test/cases/dsl-number-formatting/0005/mlr @@ -0,0 +1 @@ +$* = fmtnum($*, "%8.3e"); diff --git a/test/cases/dsl-number-formatting/0006/cmd b/test/cases/dsl-number-formatting/0006/cmd new file mode 100644 index 000000000..1c7544377 --- /dev/null +++ b/test/cases/dsl-number-formatting/0006/cmd @@ -0,0 +1 @@ +mlr --opprint --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr diff --git a/test/cases/dsl-number-formatting/0006/experr b/test/cases/dsl-number-formatting/0006/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-number-formatting/0006/expout b/test/cases/dsl-number-formatting/0006/expout new file mode 100644 index 000000000..3cae26e4e --- /dev/null +++ b/test/cases/dsl-number-formatting/0006/expout @@ -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 diff --git a/test/cases/dsl-number-formatting/0006/mlr b/test/cases/dsl-number-formatting/0006/mlr new file mode 100644 index 000000000..f0400fd31 --- /dev/null +++ b/test/cases/dsl-number-formatting/0006/mlr @@ -0,0 +1 @@ +$* = fmtifnum($*, "%8.3e"); diff --git a/test/cases/dsl-number-formatting/0007/cmd b/test/cases/dsl-number-formatting/0007/cmd new file mode 100644 index 000000000..5c77ca6c2 --- /dev/null +++ b/test/cases/dsl-number-formatting/0007/cmd @@ -0,0 +1 @@ +mlr --ojson --from test/input/ten.dkvp put -f ./${CASEDIR}/mlr diff --git a/test/cases/dsl-number-formatting/0007/experr b/test/cases/dsl-number-formatting/0007/experr new file mode 100644 index 000000000..e69de29bb diff --git a/test/cases/dsl-number-formatting/0007/expout b/test/cases/dsl-number-formatting/0007/expout new file mode 100644 index 000000000..e833f1a44 --- /dev/null +++ b/test/cases/dsl-number-formatting/0007/expout @@ -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 + } + } +} +] diff --git a/test/cases/dsl-number-formatting/0007/mlr b/test/cases/dsl-number-formatting/0007/mlr new file mode 100644 index 000000000..46209e009 --- /dev/null +++ b/test/cases/dsl-number-formatting/0007/mlr @@ -0,0 +1,5 @@ +mymap = { + "a": [2,3.4,"e"], + "f": {"g": [8, 9.1], "h": 11}, +}; +$mymap = fmtifnum(mymap, "%8.3e"); diff --git a/todo.txt b/todo.txt index 02634f376..9e8025eee 100644 --- a/todo.txt +++ b/todo.txt @@ -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