I have a not-particularly-efficient function, NumberRange, which takes two parameters: a pre-sorted text array of integers, and the array separator. It contracts any consecutive sequences between x to y to the form x–y (separated by an en rule, U+2013), removes any leading zeros and passes the resulting array through commalist(
:
functionvalue commalist(regexreplace(arrayfilter(parameter(1),parameter(2),“?(val(import())=val(array(parameter(1),seq()-1,parameter(2)))+1 and val(import())=val(array(parameter(1),seq()+1,parameter(2)))-1,"–",val(import()))”),"("+regexliteral(parameter(2))+"–)+"+regexliteral(parameter(2)),"–"),parameter(2))
This works fine when defined as a procedure, NumberRange
, within a database:
call("","NumberRange","01-03-04-06-07-08-09-10-11-13-14-15-17-19-20","-")
correctly returns the result:
1, 3, 4, 6–11, 13–15, 17, 19 and 20
However, when I substitute •1
and •2
for parameter(1)
and parameter(2)
and define it as a custom function, NUMBERRANGE
:
registercustomfunction "NUMBERRANGE",2,{commalist(regexreplace(arrayfilter(•1,•2,“?(val(import())=val(array(•1,seq()-1,•2))+1 and val(import())=val(array(•1,seq()+1,•2))-1,"–",val(import()))”),"("+regexliteral(•2)+"–)+"+regexliteral(•2),"–"),•2)}
when I try to use it the result is the error: array( function: ARRAY parameter must be text or binary.
Attempting to track down the problem, if I substitute literal string constants for •1
in each occurrence of the array(
function, that error goes away but instead I get array( function: SEPARATOR parameter must be text. Substituting a further literal string for •2
in the two array(
functions then makes that error go away. So it appears for some reason that parameter substitution isn’t working properly for the two string parameters for the array(
function, when it works fine with every other function I’ve tried. Very odd. Or am I missing something blindingly obvious?
After further thought . . .
Note that the parameter substitution within the arrayfilter(
and regexreplace(
functions works as it should. Unlike them, the array( functions here are within the arrayfilter(
formula, so that must be the problem. If the way parameter substitution works in custom functions precludes using them inside an arrayfilter(
formula that’s a pity, because arrayfilter(
lends itself especially to one-line functions. But I suppose the way round it would be to use the first function above as a custom statement, then create a custom function to call(
that statement, as I have seen done in several instances elsewhere. A pity though, when a one-line function definition is more elegant and efficient. Who doesn’t like a one-liner?
Panorama 10.2.0.b14 (3643)
MacOS 10.12.6