开发者

How does one iterate over a sequence in xquery by twos?

I want to iterate开发者_开发知识库 over a sequence in xquery and grab 2 elements at a time. What is the easiest way to do this?


XQuery 3.0 Solution

For this and more complex paging use cases the Window Clause has been created in XQuery 3.0. But, it is not yet supported by many XQuery processors.

Windowing example

Here is a working example that you could execute for example on try.zorba :

for tumbling window $pair in (2, 4, 6, 8, 10, 12, 14)
    start at $s when fn:true()
    end at $e when $e - $s eq 1
return <window>{ $pair }</window>

Result

<window>2 4</window><window>6 8</window><window>10 12</window><window>14</window>


One option is to iterate over all items and just take the items once the items reach the divisor, in this case 2. The one downside is that you won't reach the last group of items if the items aren't even multiples of the divisor. For instance, the last element of a sequence with an odd number of elements will not be returned with this approach.

for $item at $index in $items
  return
  if ($item mod 2 = 0) then
    ($items[$index - 1], $items[$index])
  else
    ()

Another option is to use mod and the index of the item. Using this approach you can make certain to include all elements in the $items sequence by adding one less than the number of items in your group to the count.

let $group-size := 2

return
for $index in (1 to fn:count($items)+($group-size - 1))[. mod $group-size = 0]
  return
  ($items[$index - 1] , $items[$index])


let $s := ("a","b","c","d","e","f")

for $i in 1 to xs:integer(count($s) div 2)
return
<pair>
   {($s[$i*2 - 1],$s[$i*2])} 
</pair>

returns

<pair>a b</pair>
<pair>c d</pair>
<pair>e f</pair>


for $item at $index in $items
return
(
    if ($index mod 2 eq 0) then
    (
        $items[xs:integer(xs:integer($index) - 1)], $items[xs:integer($index)]
    )
    else
    ()
)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜