From mixich.andreas at gmail.com Sat Aug 1 05:06:47 2020
From: mixich.andreas at gmail.com (Andreas Mixich)
Date: Sat, 1 Aug 2020 14:06:47 +0200
Subject: [xquery-talk] Purely recursive deduplication of sequence?
Message-ID: <6a075651-c649-9918-0b8b-da5968380435@gmail.com>
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}
???????????? ,
???????????? ,
???????????? , array {"apples","oranges"}
???????????? , array {"apples","oranges"}
???????????? ,
???????????? , array {"One",5,}
???????????? , array {3,7,"Hello World!"}
???????????? , array {3,7,"Hello World!"}
???????????? , map{'key':'value'}
???????????? , false()
???????????? , false()
???????????? , array {"One","lorem",,2,"Naomi"}
???????????? , array {"One", "Two", 3}
???????????? , array {"One","lorem",,2,"Naomi"}
???????????? , array {,map{'key':'value'},true()}
???????????? , false()
???????????? )
? return local:dedupe-pairs($a3)
serializes to:
? ["One","Two",3]
? ["One","Two",1]
? ["One","Two",3]
?
? ["apples","oranges"]
?
? ["One",5,]
? [3,7,"Hello World!"]
? map{"key":"value"}
? false
? ["One","lorem",,2,"Naomi"]
? ["One","Two",3]
? ["One","lorem",,2,"Naomi"]
? [,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
From christian.gruen at gmail.com Sat Aug 1 05:57:38 2020
From: christian.gruen at gmail.com (=?UTF-8?Q?Christian_Gr=C3=BCn?=)
Date: Sat, 1 Aug 2020 14:57:38 +0200
Subject: [xquery-talk] Purely recursive deduplication of sequence?
In-Reply-To: <6a075651-c649-9918-0b8b-da5968380435@gmail.com>
References: <6a075651-c649-9918-0b8b-da5968380435@gmail.com>
Message-ID:
Hi Andreas,
Try this:
declare function local:distinct-items($items as item()*) as item()* {
let $h := head($items)
where exists($h)
let $t := tail($items)[not(deep-equal(., $h))]
return ($h, local:distinct-items($t))
};
If the FLWOR expression is avoided, it may increase the runtime:
declare function local:distinct-items($items as item()*) as item()* {
if (empty($items)) then () else (
head($items),
local:distinct-items(tail($items)[not(deep-equal(., head($items)))])
)
};
Hope this helps,
Christian
On 8/1/20, Andreas Mixich wrote:
> 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}
> ???????????? ,
> ???????????? ,
> ???????????? , array {"apples","oranges"}
> ???????????? , array {"apples","oranges"}
> ???????????? ,
> ???????????? , array {"One",5,}
> ???????????? , array {3,7,"Hello World!"}
> ???????????? , array {3,7,"Hello World!"}
> ???????????? , map{'key':'value'}
> ???????????? , false()
> ???????????? , false()
> ???????????? , array {"One","lorem",,2,"Naomi"}
> ???????????? , array {"One", "Two", 3}
> ???????????? , array {"One","lorem",,2,"Naomi"}
> ???????????? , array {,map{'key':'value'},true()}
> ???????????? , false()
> ???????????? )
> ? return local:dedupe-pairs($a3)
>
> serializes to:
>
> ? ["One","Two",3]
> ? ["One","Two",1]
> ? ["One","Two",3]
> ?
> ? ["apples","oranges"]
> ?
> ? ["One",5,]
> ? [3,7,"Hello World!"]
> ? map{"key":"value"}
> ? false
> ? ["One","lorem",,2,"Naomi"]
> ? ["One","Two",3]
> ? ["One","lorem",,2,"Naomi"]
> ? [,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
> _______________________________________________
> talk at x-query.com
> http://x-query.com/mailman/listinfo/talk
From christian.gruen at gmail.com Sat Aug 1 06:21:10 2020
From: christian.gruen at gmail.com (=?UTF-8?Q?Christian_Gr=C3=BCn?=)
Date: Sat, 1 Aug 2020 15:21:10 +0200
Subject: [xquery-talk] Purely recursive deduplication of sequence?
In-Reply-To:
References: <6a075651-c649-9918-0b8b-da5968380435@gmail.com>
Message-ID:
One more solution with fold-left (it?s faster than the recursive approach):
declare function local:distinct-items($items as item()*) as item()* {
fold-left($items, (), function($result, $item) {
$result, $item[empty($result[deep-equal(., $item)])]
})
};
local:distinct-items(('x', (1 to 1000000) ! 1, 'x'))
On 8/1/20, Christian Gr?n wrote:
> Hi Andreas,
>
> Try this:
>
> declare function local:distinct-items($items as item()*) as item()* {
> let $h := head($items)
> where exists($h)
> let $t := tail($items)[not(deep-equal(., $h))]
> return ($h, local:distinct-items($t))
> };
>
> If the FLWOR expression is avoided, it may increase the runtime:
>
> declare function local:distinct-items($items as item()*) as item()* {
> if (empty($items)) then () else (
> head($items),
> local:distinct-items(tail($items)[not(deep-equal(., head($items)))])
> )
> };
>
> Hope this helps,
> Christian
>
>
>
> On 8/1/20, Andreas Mixich wrote:
>> 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}
>> ???????????? ,
>> ???????????? ,
>> ???????????? , array {"apples","oranges"}
>> ???????????? , array {"apples","oranges"}
>> ???????????? ,
>> ???????????? , array {"One",5,}
>> ???????????? , array {3,7,"Hello World!"}
>> ???????????? , array {3,7,"Hello World!"}
>> ???????????? , map{'key':'value'}
>> ???????????? , false()
>> ???????????? , false()
>> ???????????? , array {"One","lorem",,2,"Naomi"}
>> ???????????? , array {"One", "Two", 3}
>> ???????????? , array {"One","lorem",,2,"Naomi"}
>> ???????????? , array {,map{'key':'value'},true()}
>> ???????????? , false()
>> ???????????? )
>> ? return local:dedupe-pairs($a3)
>>
>> serializes to:
>>
>> ? ["One","Two",3]
>> ? ["One","Two",1]
>> ? ["One","Two",3]
>> ?
>> ? ["apples","oranges"]
>> ?
>> ? ["One",5,]
>> ? [3,7,"Hello World!"]
>> ? map{"key":"value"}
>> ? false
>> ? ["One","lorem",,2,"Naomi"]
>> ? ["One","Two",3]
>> ? ["One","lorem",,2,"Naomi"]
>> ? [,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
>> _______________________________________________
>> talk at x-query.com
>> http://x-query.com/mailman/listinfo/talk
>
From mixich.andreas at gmail.com Sat Aug 1 08:58:38 2020
From: mixich.andreas at gmail.com (Andreas Mixich)
Date: Sat, 1 Aug 2020 17:58:38 +0200
Subject: [xquery-talk] Purely recursive deduplication of sequence?
In-Reply-To:
References: <6a075651-c649-9918-0b8b-da5968380435@gmail.com>
Message-ID: <594d60e8-83d5-5f37-0e3a-c7c4dd1f3b8a@gmail.com>
Am 01.08.2020 um 14:57 schrieb Christian Gr?n:
Thank you so much for all three examples!
Of course, in the end, I am going to take the one, which has the
best performance. Do you expect it to be the `FLOWR` based or
the `fold-left#3` based, you demonstrated in the follow-up?
Still, I am glad to see this one, since it surprises me, as to how
short this can be! My own ponderings started to get out of hand by
adding more and more code - to no avail. That was when I gave up
and just asked.
> declare function local:distinct-items($items as item()*) as item()* {
> if (empty($items)) then () else (
> head($items),
> local:distinct-items(tail($items)[not(deep-equal(., head($items)))])
> )
> };
--
Goody Bye, Minden j?t, Mit freundlichen Gr??en,
Andreas Mixich
From christian.gruen at gmail.com Sat Aug 1 09:27:59 2020
From: christian.gruen at gmail.com (=?UTF-8?Q?Christian_Gr=C3=BCn?=)
Date: Sat, 1 Aug 2020 18:27:59 +0200
Subject: [xquery-talk] Purely recursive deduplication of sequence?
In-Reply-To: <594d60e8-83d5-5f37-0e3a-c7c4dd1f3b8a@gmail.com>
References: <6a075651-c649-9918-0b8b-da5968380435@gmail.com>
<594d60e8-83d5-5f37-0e3a-c7c4dd1f3b8a@gmail.com>
Message-ID:
>
> Of course, in the end, I am going to take the one, which has the
> best performance. Do you expect it to be the `FLOWR` based or
> the `fold-left#3` based, you demonstrated in the follow-up?
>
Solutions with fold-left are usually the most efficient ones, but it also
depends on the XQuery processor you use. Feel free to share your test
results.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
From mixich.andreas at gmail.com Sat Aug 15 07:08:34 2020
From: mixich.andreas at gmail.com (Andreas Mixich)
Date: Sat, 15 Aug 2020 16:08:34 +0200
Subject: [xquery-talk] Wrap element constructor and output disappears
In-Reply-To:
References:
Message-ID: <8e7aaf34-80d5-1f8a-6a79-693ad91e59f3@gmail.com>
Ihe Onwuka wrote:
> But if I try to wrap an element around that output like below nothing
> is returned
> |{ let $root := for
> $prefix in in-scope-prefixes($root)[not(. = ('xml', 'xsi'))] return
> namespace-uri-for-prefix($prefix,$root) ! value="{.}"/> } |
>
> So what is wrong and how do I wrap the output in a parameters element?
>
Not sure, whether such a late reply is of any use to you, sorry, I just
discovered it now. I want to confirm, that it works with BaseX 9.4.
The output I get is:
???
??? ?
??? ?
???
--
Goody Bye, Minden j?t, Mit freundlichen Gr??en,
Andreas Mixich