QT4CG-003-05: MK to consider how fn:array-filter() could be generalized to handle array predicates on the index as well as the value.

The following possibilities come to mind.

(a) define a new function say array:filter2($input as array(*), $predicate as function($member, $position) as xs:boolean):
In this function the predicate takes two arguments, the array member and the index position, and it decides whether to retain the member based on either or both of these arguments.

(b) allow the second argument of array:filter to be a function with either arity=1 or arity=2, with conditional logic depending on which is actually supplied. To define a usable signature for the array:filter function in this case, we really need to be able to define an argument type that is the union of two different function types. 

(c) redefine array:filter with the signature in (a), and extend the rules for function coercion so that if an arity-1 function is supplied where an arity-2 function is expected, the supplied value for the second argument is dropped. This is in fact already proposed at https://qt4cg.org/specifications/xquery-40/xpath-40-diff.html#id-function-coercion - see bullet 2.

I propose we go with (c).

Note that the filter function for arrays (and presumably for sequences) will have arguments ($value, $index), whereas the proposal for map:filter is for the arguments to be ($key, value). It might be more considered more consistent to make the map:filter callback expect ($value, $key), but my preference is to go with ($key, $value) because this is the order in map:for-each().

Note: Javascript users will be very familiar with fn:filter() and array:filter() taking a first argument that is the value of the item/member, and a second optional argument that is the position. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Michael Kay

Received on Tuesday, 20 September 2022 19:13:37 UTC