-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
array:leaves #356
Comments
I'd find the flatten-array function quite handy. I've misunderstood the current flatten function too, until realizing that it returns a sequence. |
The function name |
I often use |
The i can't say that I've seen many occasions when I would want to use the other function you're proposing either, though I've no objection to it in principle. But it's a different function and needs a different name. It's incorrect to say that the new function is lossless. You can't reconstitute the input from the output. |
As your second example leaves an empty array as itself, does that imply that |
We would stay backward compatible by adding an option to the function, maybe
A
|
Excellent questions, everyone! Thank you.
Exactly. This is why we need the new function.
I propose
It is lossless in the sense that it preserves all leaves of the input array, and their order. We are talking here if something is lost in the desired result, not about the ability to reconstitute the original. Nobody ever intended that the original could be reconstituted by the result. "Flatten" is a rather destructive operation - it decreases the dimensions of the object by at least 1.
Exactly by definition, the wanted output is:
because both inputs have a single leaf:
|
I updated the proposal (the initial issue) by renaming |
In other contexts, we're talking about |
This only describes issues in the current As for selecting all the leaves of a Comp - hierrachy (as the one described in the proposal: "CompPath (Composite-objects path) Expressions", I believe this can be expressed as:
Maybe it would be good to also have a function |
Update: As discussed in a related issue, we now have a complete proposal for the fix to this function, without affecting backwards compatibility. The fix was also refined to return not an array, but a sequence of arrays. Here is the proposed fix, and it obsoletes the initial proposal: We add a new parameter, named In the case when in a particular function call the value of this argument is In the case with all pre-4.0 code, that doesn't know about this new function parameter, its default value, Below is code implementing the new behavior, when the value of return-array-sequence is specified as
let $result := [],
$flattenBase := function($ar as array(*), $res as array(*), $self as function(*))
{
let $extractMember := function($mem as item()*)
{
if(not($mem instance of array(*)))
then array:append($res, $mem)
else $self($mem, $res, $self)
}
return
for $i in 1 to array:size($ar)
return
$extractMember($ar($i))
},
$fixedFlatten := function($ar as array(*), $return-array-sequence as xs:boolean ) as item()*
{
if($return-array-sequence) then $flattenBase($ar, $result, $flattenBase)
else (: Old, 3.1 :) array:flatten($ar)
}
return
(
"New: 
",
$fixedFlatten([1, (2, 3), 5, (), 7, [8, [10, 11, 12], (), 9]], true()),
"
Old: 
",
$fixedFlatten([1, (2, 3), 5, (), 7, [8, [10, 11, 12], (), 9]], false())
)
The new correct result (a sequence of arrays, each containing the next leaf-level member) and the old one (losing the values that are sequences) is produced with BaseX :
|
@dnovatchev Please object if you think we should we keep this one open. |
The CG decided to close this issue without further action at meeting 067. |
1. Issues
There are at least two issues with the definition of the function
array:flatten
:Unlike most other functions on arrays (such as array:put, array:replace, array:append, array:slice, array:subarray, array:remove, array:insert-before, array:tail, array:trunk, array:reverse, array:join, array:for-each, array:filter, array:for-each-pair, array:sort, array:partition) , which produce an array as their result, this function produces only a sequence
This function is not lossless -- any members that are the empty sequence or the empty array are not represented in the returned result.
2. Suggested solution(s)
We want to have a function that is similar to the wrongly defined one, but produces its contents as an array, and is lossless. There are two obvious ways to do this:
Correct the specification of
array:flatten
so that its result is an array and it represents the empty sequences and empty arrays as the same members of its result.Add to the Specification a new function:
array:leaves
that produces an array as its result and that is lossless.array:leaves returns an array whose members are exactly all the leaves of the input array, by the order of their appearance. By definition leaves are all, and at any depth, members that are not an array except when they are the empty array. Thus () (the empty sequence) and [] (the empty array) are leaves by definition.
Solution 2. will not cause any compatibility issues.
3. Examples
The expression
array:leaves([1, (), [4, 6], 5, 3])
returns[1, (), 4, 6, 5, 3]
.The expression
array:leaves([1, 2, 5], [[10, 11], 12], [], 13)
returns[1, 2, 5, 10, 11, 12, [], 13]
.The text was updated successfully, but these errors were encountered: