XQuery let for let output - for-loop

I have the following XQuery:
let $a := 0
for $b in (1,2,3)
let $a := $a + 1
return $a+$b
The result I would expect is 2,4,6
However, the result is get is 2,3,4
Why does it produce this result, i.e. why does the value of $a in the for loop stays 1?

Variables in XQuery (and XSLT) are immutable. Therefore, once declared they cannot be reassigned.

Related

XQuery concat to the same variable

Simple code there-
let $sV2 :=''
for $i in (1 to 2)
let $sV1 := 'test1'
let $sV2 := if (fn:string-length($sV2) != 0) then fn:concat($sV2,'||',$sV1) else ($sV1)
return
<test>{$sV2}</test>
i get the same output
<test>test1</test>
<test>test1</test>
whereas i expect
<test>test1</test>
<test>test1||test1</test>
what am i doing wrong? i tried to debug but why does V2 initialize to null/'' for second iteration.
Note- I have to use xquery 1.0 do to some product limitations.
How do i get the expected output?
XQuery is a functional language. As such, it does not allow you to change the value of a variable once it has been assigned.
There are many other ways to reach the same results, though. Your specific query can e.g. be rewritten as follows:
for $i in 1 to 2
return <test>{
string-join(for $n in 1 to $i return 'test1', '||')
}</test>

Pass an array to a function and output each line

I was wondering if anybody could help.
I have the below code, it has an array of variables, arr, this is being passed to the method outputArray(), I require this to output each of the individual elements on their own line, when I run this code it only outputs the value of var1 and then finishes executing. The function does return a 0 or 1 (true or false) but this is functioning as expected anyway.
function outputArray() {
for i in "$#"; do
echo $i
# Condition omitted, this would manipulate data and return either 1 or 0
}
#Variable definition omitted
arr=($var1 $var2 $var3)
if outputArray "${arr[#]}"; then
echo "True"
fi
I hope this makes sense, I don't post here often so please let me know if not and I'll try again.

wp_send_json* functions do a weird float values conversion

I have a method that does simple math and returns a float value. I use this value as an argument for wp_send_json() function. Values are converted in a way that I don't understand.
$x = $calculator->getValue(); // Returns 3.02
$y = 3.02;
gettype($x); // Returns double
gettype($y); // Returns bouble
wp_send_json_success(%x); // prints {"success":false,"data":3.0199999999999996}
wp_send_json_success($y); // prints {"success":false,"data":3.02}
I don't' understand it at all. Both $x and $y values are exactly the same in terms of values and types. So why the outputs produced by wp_send_json_success are different?
Update:
Now I'm even more confused
$x === $y; // returns false
$x == $y; // returns false too!
How is it possible? When I do var_dump I can see that the values are the same.
It has nothing to do with wp_send_json(). In my code the 3.02 value returned by the $calculator->getValue() method is a result of a 10 - 6.98 equation. It returns 3.0199999999999996 but when I var_dump it then the result on the screen is rounded to 3.02. That's why $x == $y returns false.

Is it possible to pass parameters by reference in Rebol?

Here, I have attempted to set the value of a global variable from inside a function, but the value has not changed:
setGlobalScope: func [theVar1] [
theVar1: 10
]
theVar: 1
setGlobalScope theVar
print theVar
"This prints 1 instead of 10. The value of theVar has not changed."
Is it possible to modify the value of a function's parameter from inside the function itself, so that the value is modified within the global scope instead of the function's scope?
You passed an integer value, not a word. Within the function, the word theVar1 is assigned the value of that integer. Reassigning it doesn't change it, because values like integers and dates and decimal numbers aren't "pointers" under the hood.
Hence, the answer from #sqlab where you can get around this by various ways of getting the word itself. The difference between function ['x] [code] and function [:x] [code] may interest you as an aside...
Why doesn't Rebol 3 honor quoted function parameters that are parenthesized?
But note that series values in Rebol do have modifying functions that affect the target, vs. just reassignment of where the word points. Consider:
setGlobalScope: func [theVar1 [string!]] [
clear theVar1
insert theVar1 "Modification"
]
theVar: "Original"
setGlobalScope theVar
print theVar
That prints Modification.
If you need to pass non-series values by reference, you need to put them in a series and use series modification operations instead of assignment. Because an assignment would just overwrite the "pointer" you have to the block or whatever. Worst case scenario you can wrap a single value in a block--if you must. But Rebol has a lot of "wait, look at it this other way..." where dialecting comes to the rescue in creating a better interface than that thing you were trying to clone from another less cool language. :-)
Mitigating the complexity of passing by reference is Rebol's simplicity at handling multiple return results:
foo: function [value1 value2] [
return reduce [
value1 + 7
value2 + 16
]
]
set [a b] foo 03 04
print a
print b
That outputs 10 and 20.
By using a combination of lit-word and get-word there is more than one way.
e.g
>> setGlobalScope: func ['theVar1] [set :theVar1 10]
>> theVar: 1
== 1
>>
>> setGlobalScope theVar
== 10
>>
>> print theVar
10
and
>> setGlobalScope: func [theVar1] [set :theVar1 10]
>> theVar: 1
== 1
>> setGlobalScope 'theVar
== 10
>> print theVar
10
I think you can just modify your variable theVar directly in your setGlobalScope funct.

xquery- how to obtain min/max value from a set of values that are obtained by subtracting consecutive members from a list

In an xquery expression, I have obtained a set of values within a for-expression, and one value is in a separate variable.
Now, I want to subtract the single value from first value of the list, and then subtract consecutive members of the list from each other-- and in the resulting set of difference values, I want to obtain the min/max values...
The query upto now looks like this--
let $value1:= 1998
let $rows_citations:=
$doc//div[#id="patent_citations"]
/div[#id="patent_citations_v"]
/table[#class="rel_patent"]
/tbody/tr[1]
/following-sibling::tr
for $pos in $rows_citations/position()
let $date2_c := customfn:dateconverter1($rows_citations[$pos]/td[3])
Now the subtraction I want is between first value of date2_c and value 1, and after that between consecutive members of date2_c... And from the resulting list I want the min/max values... How do I go about doing this?
I am esp. confused about creating a new list variable that stores all the differences, esp. when we are already inside a for loop, and are iterating over each value of a list (via variable date2_c)
I. This XQuery 3.0 query (which is also a pure XPath 3.0 expression):
let $pVal := 1,
$vList := (2,4,7,11,16),
$vList2 := ($pVal, subsequence($vList, 1, count($vList)-1)),
$vSubtactedList :=
map-pairs(function($m as xs:integer, $n as xs:integer) as xs:integer
{
$m - $n
},
$vList,
$vList2
)
return
(min($vSubtactedList), max($vSubtactedList))
produces the wanted result the minimum and maximum values from the list of subtractions:
1 5
II. XQuery 1.0 solution:
let $pVal := 1,
$vList := (2,4,7,11,16),
$vList2 := ($pVal, subsequence($vList, 1, count($vList)-1)),
$vSubtactedList :=
for $i in 1 to count($vList)
return
$vList[$i] - $vList2[$i]
return
(min($vSubtactedList), max($vSubtactedList))
This again produces the same correct result:
1 5

Resources