xquery- how to get difference between successive values in a list of numeric values
-
07-07-2021 - |
문제
I have extracted successfully one value in one variable, and a list of values in another variable (as part of my XQuery expression).
Now, suppose the single-value variable is
x=1
and the list variable is named y with values 2,4,7,11,16
I want to extract the following values -- (2-1), (4-2), (7-4), (11-7), (16-11)
ie, first value of list variable minus single value variable, then differences between successive members of the list variable.
I tried using
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...
but nothing is shown at all as output... What am I doing wrong here?
해결책
I. With XQuery 3.0 / Xpath 3.0, use:
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
)
This produces the wanted, correct result:
1 2 3 4 5
II. XQuery 1.0 solution:
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]
again produces the same correct result:
1 2 3 4 5
Performance comparison:
Surprizingly, the XPath (XQuery) 3.0 query is executed almost twice faster than the XQuery 1.0 one -- when run on BaseX.
다른 팁
Your example is so abstract, it is really not clear what you tried to use.
But you can subtract $x or the previous element like this:
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]
Remember to use 'at $pos' if you want the position.
(And btw, XQuery 3 also has the window clause just for this case:
Would probably look like this:
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]
does not appear to be easier, but it is cooler)