'use the result of a function call in a loop in next iterations of the loop in XQuery

I am new to XQuery and I have came to a problem that I cannot solve. Imagine that we have a for loop and in this for loop we call a function that outputs a result. The question is how to use this result in next iteration of this for loop?

Here is a really simple example. Bare in mind that this is just to show what I want.

This is the XML file:

<data>
<d><val>5</val></d> 
<d><val>6</val></d> 
<d><val>7</val></d> 
<d><val>8</val></d> 
<d><val>9</val></d> 
<d><val>10</val></d> 
</data>

and here is my query

declare function local:do-stuff($val1, $val2){
    let $sum := $val1 + $val2 return $sum 
};

<res>
{ 
    for $elem1 in fn:doc("test.xml")//val 
        for $elem2 in fn:doc("test.xml")//val 
            let $res := local:do-stuff($elem1, $elem2) 
            return <val>{$res}</val> 
} 
</res>

What I want is to see if variable $res in for loops has been already calculated in previous iterations and if it is the case, I dont call do-stuff function and I go to next iteration. Thank you in advanced for your help



Solution 1:[1]

A for expression is not an iterative loop, it is a functional mapping from an input sequence to an output sequence.

If you want to do sequential processing where the result of processing one item depends on the results of processing previous items, there are two approaches possible:

(a) write a recursive function, typically head-tail recursion, where the function processes one item in the sequence (the head) and then calls itself to process the rest of the sequence (the tail), passing any partial results as parameters

(b) with XQuery 3.1, using the fold-left() function, which applies a user-supplied function to each item in the sequence in turn, accumulating a result: for example fold-left($input, 1, function($a, $b){$a * $b}) computes the product of a sequence of numbers.

To apply this to your case, the intermediate result might be a sequence or map of all the previously-computed values.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Michael Kay