Reputation: 13
I'm not getting the output I want. I don't understand why the result is duplicated. Can someone help me?
for $i in 1 to 2
let $rng:=random-number-generator()
let $rng1:=$rng('permute')(1 to 10)
let $rng:=$rng('next')()
let $rng2:=$rng('permute')(1 to 10)
let $rng:=$rng('next')()
let $rng3:=$rng('permute')(1 to 10)
return (string-join($rng1),string-join($rng2),string-join($rng3),",")
result:
23496815107
31018674529
31017684259
23496815107
31018674529
31017684259
Upvotes: 1
Views: 159
Reputation: 163342
The specification is here:
http://www.w3.org/TR/xpath-functions-31/#func-random-number-generator
It says:
Both forms of the function are ·deterministic·: calling the function twice with the same arguments, within a single ·execution scope·, produces the same results.
If you supply $i
as the $seed
argument to random-number-generator then the two sequences should be different.
Upvotes: 1
Reputation: 7279
I think I now understand what confuses you in this original query. One could indeed expect the random numbers to be generated differently for each iteration of $i.
However, XQuery is (to put it simply, with a few exceptions) deterministic. This means that the random generator probably gets initialized in each iteration with the same, default seed.
Thus, I have a second potential answer:
If you have a way to pass a different seed to $rng, you could slightly modify your initial query by constructing a seed based on $i and maybe current-dateTime() in each iteration before generating the numbers. But it will still be the same if you execute the query several times unless you involve the current date/time.
Upvotes: 0
Reputation: 7279
The result is duplicated because of the initial for $i in 1 to 2
, and because the variable $i
is not actually used anywhere.
I edited the query based on your comment (getting 10 numbers). From what I understand, the difficulty here is to chain the calls (alternating between 'next' and 'permute'). Chaining calls can be done with a tail recursion.
declare function local:multiple-calls(
$rng as function(*),
$number-of-times as xs:integer) as item()* {
if($number-of-times le 0)
then ()
else
let $rng := $rng('next')
return ($rng('permute')(1 to 10),
local:multiple-calls($rng, $number-of-times - 1))
};
local:multiple-calls(random-number-generator(), 10)
Note: I am not sure if (1 to 10) is what needs to actually be passed to the call to $rng('permute'), or if it was an attempt to output ten numbers. In doubt, I haven't changed it.
Upvotes: 1