[xquery-talk] Purely recursive deduplication of sequence?
Andreas Mixich
mixich.andreas at gmail.com
Sat Aug 1 05:06:47 PDT 2020
Hello,
I wonder, whether it could be possible to deduplicate a sequence by a
purely recursive approach,
without creating state in any form.
What I have, so far, is only capable of removing consecutive dupes, so,
nothing fancy.
(:~
Removes all consecutive duplicate items from a sequence, returning
the deduped sequence.
@param $items a sequence, that may contain duplicates
@return a sequence, in which all 'pairs' have been 'singled'
:)
declare function local:dedupe-pairs($items as item()*) as item()* {
if (count($items) <= 1)
then $items
else if (deep-equal(head($items), head(tail($items))))
then local:dedupe-pairs(tail($items))
else (
head($items)
, local:dedupe-pairs(tail($items))
)
};
(: following sequence has 19 items :)
let $a3 := (
array {"One", "Two", 3}
, array {"One", "Two", 1}
, array {"One", "Two", 3}
, <xml></xml>
, <xml></xml>
, array {"apples","oranges"}
, array {"apples","oranges"}
, <xml></xml>
, array {"One",5,<xml></xml>}
, array {3,7,"Hello World!"}
, array {3,7,"Hello World!"}
, map{'key':'value'}
, false()
, false()
, array {"One","lorem",<xml></xml>,2,"Naomi"}
, array {"One", "Two", 3}
, array {"One","lorem",<xml></xml>,2,"Naomi"}
, array {<xml></xml>,map{'key':'value'},true()}
, false()
)
return local:dedupe-pairs($a3)
serializes to:
["One","Two",3]
["One","Two",1]
["One","Two",3]
<xml/>
["apples","oranges"]
<xml/>
["One",5,<xml/>]
[3,7,"Hello World!"]
map{"key":"value"}
false
["One","lorem",<xml/>,2,"Naomi"]
["One","Two",3]
["One","lorem",<xml/>,2,"Naomi"]
[<xml/>,map{"key":"value"},true()]
false
However, this is not what I want. I want to understand, whether a
function would be possible, that completely dedupes given sequence,
like `fn:distinct-values#1`, however, for any kind of item, not just
atomic ones:
`local:distinct-items($items as item()*) as item()*`
It should no use state in any form (typically creating and revolving
a second list or sending a flag throughout recursion).
Also, I do not want to use any manipulative functions (like fn:remove#2)
and, ideally, no `FOR..IN..` construct.
The deduped list would be purely the result of the recursive walk through
the list, grown organically, so to say.
Only, I can not come up with such a thing. Is there a way to do it?
Thank you.
--
Goody Bye, Minden jót, Mit freundlichen Grüßen,
Andreas Mixich
More information about the talk
mailing list