Andy Chan
Andy Chan

Reputation: 133

Count Number of times a nested FLWOR loop runs in XQuery

If you had a nested FLWOR statement like this with two 'for' statements:

for $x at $xPos in (1, 2, 3)
 for $y at $yPos in fn:doc("/foo")//b
return ()

How would you count exactly how many times the for loop ran? Assume 'fn:doc("/foo")//b' returns sequences in random length, so here is an example run:

$xPos  $yPos
1       1
1       2
1       3
2       1
2       2
3       1 <-- for loop ends here (total times ran = 6)

And another example run could be:

$xPos  $yPos
1       1
1       2
2       1
2       2
2       3
3       1
3       2
3       3
3       4 <-- for loop ends here (total times ran = 9)

Well hopefully, you get my point. How do I keep and update a counter variable within the nested for loop to count how many times I ran through this loop without having it reset at every iteration of the loop?

Clarification EDIT: This question is just based on pure curiosity to know if this is possible in XQuery. I know that you can just simply put a let statement like so and just keep track of $xPos which is a simple matter:

for $x at $xPos in (1, 2, 3)
let $_ :=
 for $y at $yPos in fn:doc("/foo")//b
 return ()
return ()

Upvotes: 2

Views: 449

Answers (3)

grtjn
grtjn

Reputation: 20414

How about just counting afterwards:

for $x at $xPos in (1, 2, 3)
let $c :=
 for $y at $yPos in fn:doc("/foo")//b
 return 1
return count($c)

HTH!

Upvotes: 1

hunterhacker
hunterhacker

Reputation: 7142

In MarkLogic you can use xdmp:set to break out of the strict FLWOR paradigm.

let $count := 0
for $x at $xPos in (1, 2, 3)
for $y at $yPos in ("a", "b", "c")
let $set := xdmp:set($count, $count + 1)
return concat($count, ": ", $x, " ", $y)

Produces:

1: 1 a
2: 1 b
3: 1 c
4: 2 a
5: 2 b
6: 2 c
7: 3 a
8: 3 b
9: 3 c

Upvotes: 3

Martin Honnen
Martin Honnen

Reputation: 167716

XQuery 3 has a count clause (https://www.w3.org/TR/xquery-31/#id-count):

for $x in (1 to 3)
for $y in //b
count $c
return ``[count `{$c}`: y: `{$y}`]``

https://xqueryfiddle.liberty-development.net/6qVRKvF for the input

<doc>
    <b>a</b>
    <b>b</b>
    <b>c</b>
</doc>

returns the result

count 1: y: a
count 2: y: b
count 3: y: c
count 4: y: a
count 5: y: b
count 6: y: c
count 7: y: a
count 8: y: b
count 9: y: c

However, if I interpret https://docs.marklogic.com/guide/xquery/langoverview#id_11626 correctly, then Marklogic doesn't support the count clause.

Upvotes: 2

Related Questions