How to collect attributes and values in function - function

I am trying do this:
I want to do function which receives
one node as a parameter. and I it should return a string.
so I need to loop node and I don't know more details,
but I want to concatenate a new json type of string
and returns it.
but seems to be difficult, because I don't know xquery well.
my idea is
declare function local:Do_the_thing($my_node as node()*) as xs:string{
for ($element at $col in (attribute_list($my_node))
let $complete_row_information := concat ("test", "test2");
return $complete_row_information
}
can someone say me, what is going wrong and how to fix it?
if this thing is not in a function it works

Related

How to remove duplicate results from a cts:uris when distinct values does not work

I have the following code that returns an array of array of results I try to use distinct-values to remove duplicates and it does nothing I have tried also removing using looping functions by comparing values with no success.
I have tried converting to "xs anyAtomicType" and using distinct values
I have tried putting in json array and extracting the sub-array
I have tried tokenizing, xdmp quote, string-before/after and many others
declare function local:verify-user-uri($dir as xs:string)
{
for $each in cts:uris($dir, ())
let $uIds := (for $d in $each
where contains($d, "/profile.xml")
return $d)
return $uIds
};
I get back duplicated result in form of:
/users/123-343-/profile.xml
/users/122-222-/profile.xml
/users/123-343-/profile.xml
/users/122-222-/profile.xml
/users/123-343-/profile.xml
/users/122-222-/profile.xml
I am expecting:
/users/123-343-/profile.xml
/users/122-222-/profile.xml
Is it possible that you have simply invoked this function 3 times and didn't realize it?
You have declared $dir to be a single xs:string. If your $dir happened to be a sequence of strings of the same directory, or if you otherwise invoked the function 3 times with the directory variable.
It can easily happen with function mapping enabled (default behavior). https://docs.marklogic.com/guide/xquery/enhanced#id_55459
There are a couple of things that you can do as a diagnostic:
1.) Remove the explicit type on the $dir parameter in the function:
declare function local:verify-user-uri($dir)
{
for $each in cts:uris($dir, ())
let $uIds := (for $d in $each
where contains($d, "/profile.xml")
return $d)
return $uIds
};
do you get an error executing cts:uris() that looks like this:
[1.0-ml] XDMP-ARGTYPE: )err:XPT0004) cts:uris(("/users/", "/users/", "/users/"), ()) -- arg1 is not of type xs:string?
2.) try disabling function mapping by adding the following to the prolog:
declare option xdmp:mapping "false";
and see if you then get an invalid coercion error like:
[1.0-ml] XDMP-AS (err:XPTY0004) $dir as xs:string -- Invalid coersion ("/users/", "/users/", "/users/") as xs:string
3.) You could also add something to the end of the sequence of values returned from the function to indicate how many times it has executed:
declare function local:verify-user-uri($dir as xs:string)
{
for $each in cts:uris($dir, ())
let $uIds := (for $d in $each
where contains($d, "/profile.xml")
return $d)
return $uIds, "#"
};
And see how many times you see "#" in the result. If more than one, you are invoking the function multiple times.
Next to the good suggestions from Mads, I notice a couple of other things about your code:
It doesn't make sense to iterate over $each as it contains one uri only. Keep in mind that a FLWOR statement ends with a return, which tells what should be the result per item
Beware that the first arg to cts:uris only marks a start, not an end. If you feed in /aaa/, you also get back /bbb/ etc, though not vice versa.
To be honest, I think you are looking for cts:uri-match() instead, which would reduce your function to a one-liner:
declare function local:verify-user-uri($dir as xs:string) {
cts:uri-match($dir || "*/profile.xml")
};
HTH!
PS: I do recommend always disabling function mapping as Mads recommends. It can prevent a lot of confusion.

How to make array from MySQL ROW type?

I am using mysql-native driver. My code:
ResultRange MySQLTablesRange = mysqlconnection.query(`SELECT historysensor FROM TableName`);
auto historysensor = MySQLTablesRange.array.filter!(a=>a[0].coerce!string.canFind("historysensor"));
But on send string I am getting to historysensor not an array, but structure like: Row([historysensor_10774], [false]).
So every time to get value I need to do a lot of casting like:
foreach(sensor;historysensor)
{
writeln(sensor[0].coerce!string.split("_")[1]);
}
How I can make historysensor as simple array, to be able to work without [0].coerce!string?
You can just map it before doing the other stuff
auto historysensor = MySQLTablesRange.array.
map!(a => a[0].coerce!string). // this is new
filter!(a.canFind("historysensor"). // no need for coerce here now
array; // convert to plain array of strings
BTW using filter here is probably a mistake too, make that part of your query so the database does it, that would be likely more efficient and easier to read.

How do I return JSON from an action in CFWheels?

I've been reading a lot about returning JSON in CFWheels...it all looks straight forward, but all I ever get is a blank page with no JSON returned. I may be doing something really obviously wrong here.
Here's my action:
public void function ajax() {
param name="params.keyword" default="";
onlyProvides("json");
pins = model("pin").findAll(
include = "user",
order = "createdat DESC",
where = "title LIKE '%#cleanInput(application.jsoup, params.keyword)#%'"
);
renderWith(data=pins, layout=false);
}
I can confirm that searching on a word and dumping the query result reveals a record, but when it's like above, all I get is a blank screen. Am I missing something here?
I want to return the query object in JSON. Is there something I have to actually output in my view? I could do this, but wante to do it all from the action as I thought it would?
Thanks,
Mikey.
Just off the top of my head are you passing Format=JSON in your ajax call? If not the controller will not return JSON.

Lua - Execute a Function Stored in a Table

I was able to store functions into a table. But now I have no idea of how to invoke them. The final table will have about 100 calls, so if possible, I'd like to invoke them as if in a foreach loop. Thanks!
Here is how the table was defined:
game_level_hints = game_level_hints or {}
game_level_hints.levels = {}
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
},
[on_scene("scene1")] =
{
talk("hint0"),
talk("hint1"),
talk("hint2")
}
}
end
Aaand the function definitions:
function on_scene(sceneId)
-- some code
return sceneId
end
function talk(areaId)
-- some code
return areaId
end
EDIT:
I modified the functions so they'll have a little more context. Basically, they return strings now. And what I was hoping to happen is that at then end of invoking the functions, I'll have a table (ideally the levels table) containing all these strings.
Short answer: to call a function (reference) stored in an array, you just add (parameters), as you'd normally do:
local function func(a,b,c) return a,b,c end
local a = {myfunc = func}
print(a.myfunc(3,4,5)) -- prints 3,4,5
In fact, you can simplify this to
local a = {myfunc = function(a,b,c) return a,b,c end}
print(a.myfunc(3,4,5)) -- prints 3,4,5
Long answer: You don't describe what your expected results are, but what you wrote is likely not to do what you expect it to do. Take this fragment:
game_level_hints.levels["level0"] = function()
return
{
[on_scene("scene0")] =
{
talk("hint0"),
}
}
end
[This paragraph no longer applies after the question has been updated] You reference on_scene and talk functions, but you don't "store" those functions in the table (since you explicitly referenced them in your question, I presume the question is about these functions). You actually call these functions and store the values they return (they both return nil), so when this fragment is executed, you get "table index is nil" error as you are trying to store nil using nil as the index.
If you want to call the function you stored in game_level_hints.levels["level0"], you just do game_level_hints.levels["level0"]()
Using what you guys answered and commented, I was able to come up with the following code as a solution:
asd = game_level_hints.levels["level0"]()
Now, asd contains the area strings I need. Although ideally, I intended to be able to access the data like:
asd[1][1]
accessing it like:
asd["scene0"][1]
to retrieve the area data would suffice. I'll just have to work around the keys.
Thanks, guys.
It's not really clear what you're trying to do. Inside your anonymous function, you're returning a table that uses on_scene's return value as keys. But your on_scene doesn't return anything. Same thing for talk.
I'm going to assume that you wanted on_scene and talk to get called when invoking each levels in your game_level_hints table.
If so, this is how you can do it:
local maxlevel = 99
for i = 0, maxlevel do
game_level_hints.levels["level" .. i] = function()
on_scene("scene" .. i)
talk("hint" .. i)
end
end
-- ...
for levelname, levelfunc in pairs(game_level_hints.levels) do
levelfunc()
end

AS3 ... (rest) parameter

I've tested the following code:
function aa(...aArgs):void
{
trace("aa:", aArgs.length);
bb(aArgs);
}
function bb(...bArgs):void
{
trace("bb:", bArgs.length);
}
aa(); //calling aa without any arguments.
The output is:
aa: 0 //this is expected.
bb: 1 //this is not!
When I pass empty arguments (aArgs) to bb function;
shouldn't it return 0 length? Seems like function bb is treating the passed aArgs as non-empty / non-null..
What am I missing here?
Any help is appreciated.
regards..
It looks like aArgs going to the bb() function would be an empty array, but an array none the less... I would say that output is to be expected. I'm not really sure though how I would format it differently though to get the desired output...
Update 1:
I wanted to clarify a little bit. What you have is basically the same thing as:
function aa(...aArgs):void
{
myArray:Array = aArgs;
bb(myArray);
}
function bb(...bArgs):void
{
trace("bb:", bArgs.length);
}
aa(); //calling aa without any arguments.
If you saw this code, you would expect bb:1 yes?
Update 2:
This thread: filling in (...rest) parameters with an array? looks as though it would be relevant. It uses the apply() function to pass in an array as an parameter list. http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/Function.html#apply()
Don't know if this is still relevant but you could try this:
function aa(...aArgs):void {
var myArray:Array = aArgs;
bb.apply( this, myArray );
}
function bb(...bArgs):void {
trace("bb:", bArgs.length);
}
aa(); //calling aa without any arguments.
Basically Function.apply is your friend here.
This makes perfect sense, and working properly. ...rest always creates an Array, if there are no values passed in it creates an empty Array, as you see by tracing its length. So the reason why bb has one object in its ...rest array is that you are passing the empty array into bb as a value, which gets inserted into the first position of the Array generate by bb's ...rest, giving it a length of one.