You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
map() can be used to process each element of the array: [111, 222, 333] * 1.05 | map(@, &round(@, 2)) :
[
116.55,
233.1,
349.65
]
2. Use a projection
If we turn the expression into a projection, we can apply the round() function to each element in the projection:
( [111, 222, 333] * 1.05 )[].round(@, 2)) will also produce: [116.55, 233.1, 349.65]
However, both of these are advanced usage -- not easily discovered.
Allow functions to accept arrays
To make this easier, we could allow round() to accept either a number or an array of numbers as its first parameter. When given a number, will produce a number result, when given an array, will produce an array result:
Excel allows ranges of values to be passed to functions. e.g. The first parameter to round() can be a single cell or a range of cells.
In fact, Excel allows either (or both) parameters to be arrays. e.g. Excel supports the equivalent of:
Note that this would be a breaking change to json-formula, since it means we could no longer coerce values for many functions.
e.g. today the expression: round("7.2") will produce 7. We coerce the string "7.2" to a number, because we know the first parameter must be a number.
However, with this change, we don't know whether to coerce to a number or array, so the call will fail. A breaking change means we'd need to bump our version number to 2.0.0
Change Coercion Rules?
If we're introducing a breaking change, we could break in a different manner and loosen the rules about function parameter coercion.
Today we refuse to attempt coercion when there are multiple allowable parameter types.
That means that this call would fail: round(["7.2", "8.1"]), since the parameter is neither a number or array of numbers.
However, in this case we should be able to coerce the array of strings to an array of numbers since there is no available coercion to turn an array of strings into a number.
Changes to coercion rules will be proposed as a separate issue.
Consistency with operators
This change would be consistent with our array operators.
e.g. today we support
i.e. we allow scalar operands to match with array operands.
In regards to array operators, the spec states:
When both operands are arrays, a new array is returned where the elements are populated by applying the operator on each element of the left operand array with the corresponding element from the right operand array
If both operands are arrays and they do not have the same size, the shorter array is padded with null values
If one operand is an array and one is a scalar value, a new array is returned where the operator is applied with the scalar against each element in the array
For operands to functions the rules need to be stated differently, since there can be more than 2 operands:
When any operand is an array then:
All operands will be treated as arrays
Any scalar operands will be converted to an array by repeating the scalar value
All arrays will be padded to the length of the longest array by adding null values
Note that we would not extend this to unary operators.
e.g. ![true(), false()] returns false, not [false, true]
Note that while Excel supports ranges with the not() function, we propose that json-formula doesn't -- for the reason that we do not want to change the behavior of unary not (!) and do not want unary not and the function not() to be inconsistent. Excel doesn't have this issue, because it does not have unary operators.
Proposal
Where appropriate, change function definitions to allow them to process arrays of values instead of single values.
The affected functions include:
abs
acos
asin
atan2
casefold
ceil
codePoint
cos
datedif
day
endsWith
eomonth
exp
find
floor
fround
hour
log
log10
lower
millisecond
minute
mod
month
power
proper
rept
round
search
second
sign
sin
split
sqrt
startsWith
substitute
tan
trim
trunc
upper
weekday
year
unaffected functions
We don't want to change these categories of functions:
Functions that already take an array as a parameter. i.e. we're not looking to process arrays of arrays (avg, min, max, stdev, stdevp, join, length, sort, unique ...)
Functions that allow a variable number of parameters (merge, notNull ...)
logic functions (and, not, if, or)
functions without parameters (null, true, false, now, today, random...)
The change to allowing arrays in functions highlights a separate change we'd prefer to make to fromCodePoint().
The fromCodePoint() function currently takes a single integer parameter to produce a character. e.g. fromCodePoint(65) => "A"
However the JavaScript version allows multiple parameters to create a string. e.g. String.fromCodePoint(65, 66, 67) => "ABC"
For our updated fromCodePoint() method, we should have the array version return a string instead of an array of characters.
i.e. fromCodePoint([65, 66, 67]) => "ABC"
The text was updated successfully, but these errors were encountered:
We often have cases where we want to execute a function on each element of an array.
For example, if we execute this expression:
[111, 222, 333] * 1.05
we get:and want to round the results.
There area a couple things that a user might try that will not work:
round([111, 222, 333] * 1.05)
(results in a TypeError, since round() is not expecting an array.([111, 222, 333] * 1.05).round(@)
(same TypeError).There are two ways we can round the values:
1. use
map()
map()
can be used to process each element of the array:[111, 222, 333] * 1.05 | map(@, &round(@, 2))
:2. Use a projection
If we turn the expression into a projection, we can apply the
round()
function to each element in the projection:( [111, 222, 333] * 1.05 )[].round(@, 2))
will also produce:[116.55, 233.1, 349.65]
However, both of these are advanced usage -- not easily discovered.
Allow functions to accept arrays
To make this easier, we could allow
round()
to accept either a number or an array of numbers as its first parameter. When given a number, will produce a number result, when given an array, will produce an array result:round([111, 222, 333] * 1.05, 2)
or([111, 222, 333] * 1.05).round(@, 2)
will produce:
[1.12, 2.35, 3.46]
.Consistency with Excel
Excel allows ranges of values to be passed to functions. e.g. The first parameter to
round()
can be a single cell or a range of cells.In fact, Excel allows either (or both) parameters to be arrays. e.g. Excel supports the equivalent of:
round([1.111, 2.222, 3.333], 1)
=>[1.1, 2.2, 3.3]
round([1.111, 2.222, 3.333], [1,2,3])
=>[1.1, 2.22, 3.333]
round(1.111, [1,2,3])
=>[1.1, 1.11, 1.111]
Breaking change
Note that this would be a breaking change to json-formula, since it means we could no longer coerce values for many functions.
e.g. today the expression:
round("7.2")
will produce7
. We coerce the string "7.2" to a number, because we know the first parameter must be a number.However, with this change, we don't know whether to coerce to a number or array, so the call will fail. A breaking change means we'd need to bump our version number to
2.0.0
Change Coercion Rules?
If we're introducing a breaking change, we could break in a different manner and loosen the rules about function parameter coercion.
Today we refuse to attempt coercion when there are multiple allowable parameter types.
That means that this call would fail:
round(["7.2", "8.1"])
, since the parameter is neither a number or array of numbers.However, in this case we should be able to coerce the array of strings to an array of numbers since there is no available coercion to turn an array of strings into a number.
Changes to coercion rules will be proposed as a separate issue.
Consistency with operators
This change would be consistent with our array operators.
e.g. today we support
[1,2,3] + [2,3,4]
=>[3,5,7]
[1,2,3] + 3
=>[4,5,6]
i.e. we allow scalar operands to match with array operands.
In regards to array operators, the spec states:
For operands to functions the rules need to be stated differently, since there can be more than 2 operands:
Note that we would not extend this to unary operators.
e.g.
![true(), false()]
returnsfalse
, not[false, true]
Note that while Excel supports ranges with the
not()
function, we propose that json-formula doesn't -- for the reason that we do not want to change the behavior of unary not (!
) and do not want unary not and the functionnot()
to be inconsistent. Excel doesn't have this issue, because it does not have unary operators.Proposal
Where appropriate, change function definitions to allow them to process arrays of values instead of single values.
The affected functions include:
unaffected functions
We don't want to change these categories of functions:
Functions that already take an array as a parameter. i.e. we're not looking to process arrays of arrays (avg, min, max, stdev, stdevp, join, length, sort, unique ...)
Functions that allow a variable number of parameters (merge, notNull ...)
logic functions (and, not, if, or)
functions without parameters (null, true, false, now, today, random...)
introspection/transformation functions (value, keys, values, hasProperty, entries, fromEntries, toArray, toDate, toNumber, toString, zip...)
and
avg
contains
datetime
debug
deepScan
entries
false
fromEntries
hasProperty
if
join
keys
left
length
map
max
merge
mid
min
not
now
notNull
null
or
random
reduce
register
replace
reverse
right
sort
sortBy
stdev
stdevp
sum
time
toArray
toDate
today
toNumber
toString
true
type
unique
value
values
zip
Change fromCodePoint()
The change to allowing arrays in functions highlights a separate change we'd prefer to make to
fromCodePoint()
.The
fromCodePoint()
function currently takes a single integer parameter to produce a character. e.g.fromCodePoint(65) => "A"
However the JavaScript version allows multiple parameters to create a string. e.g.
String.fromCodePoint(65, 66, 67) => "ABC"
For our updated
fromCodePoint()
method, we should have the array version return a string instead of an array of characters.i.e.
fromCodePoint([65, 66, 67]) => "ABC"
The text was updated successfully, but these errors were encountered: