xquery-как получить разницу между последовательными значениями в списке числовых значений

Я успешно извлек одно значение из одной переменной и список значений из другой переменной (как часть моего выражения XQuery).

Теперь предположим, что однозначная переменная

x=1

и переменная списка называется y со значениями 2,4,7,11,16

Я хочу извлечь следующие значения -- (2-1), (4-2), (7-4), (11-7), (16-11)

т. е. первое значение переменной списка минус переменная с одним значением, затем различия между последовательными элементами переменной списка.

я пытался использовать

for $pos in list-variable/position() 
-> if clause for $pos=1 (to subtract and shown list variable- single value variable)    
->else show difference b/w consecutive list variables... 

но на выходе вообще ничего не отображается... Что я здесь делаю не так?


person Arvind    schedule 16.10.2012    source источник


Ответы (2)


И. С XQuery 3.0/Xpath 3.0 используйте:

let $pVal := 1,
    $vList := (2,4,7,11,16),
    $vList2 := ($pVal, subsequence($vList, 1, count($vList)-1))
 return
    map-pairs(function($m as xs:integer, $n as xs:integer) as xs:integer
                {
                 $m - $n
                },
                $vList,
                $vList2
              )

Это приводит к желаемому правильному результату:

1 2 3 4 5

II. Решение XQuery 1.0:

let $pVal := 1,
    $vList := (2,4,7,11,16),
    $vList2 := ($pVal, subsequence($vList, 1, count($vList)-1))
 return
    for $i in 1 to count($vList)
     return
        $vList[$i] - $vList2[$i]

снова дает тот же правильный результат:

1 2 3 4 5

Сравнение эффективности:

Удивительно, но запрос XPath (XQuery) 3.0 выполняется почти в два раза быстрее, чем запрос XQuery 1.0 — при запуске на BaseX.

person Dimitre Novatchev    schedule 16.10.2012
comment
если мне также нужно минимальное/максимальное значение из результирующего списка, как мне это сделать? (В xquery 1/xquery 3)? Спасибо... - person Arvind; 17.10.2012

Ваш пример настолько абстрактен, что действительно непонятно, что вы пытались использовать.

Но вы можете вычесть $x или предыдущий элемент следующим образом:

 let $x := 1, $seq := (2,4,7,11,16)  
 for $temp at $pos in $seq 
 return $seq[$pos] - if ($pos eq 1) then $x else $seq[$pos - 1]

Не забудьте использовать at $pos, если вам нужна позиция.

(Кстати, XQuery 3 также имеет предложение окна только для этого случая:

Вероятно, это выглядело бы так:

 let $x := 1, $seq := (2,4,7,11,16) 
 for sliding window $w in ($x, $seq)
     start at $s when fn:true()
     only end at $e when $e - $s eq 1
 return $w[2] - $w[1]

вроде не легче, а круче)

person BeniBela    schedule 16.10.2012