I have a form list in a tuple in the following format and a current page
CurrPageName = "ihtx_f_10_00_00_00_00_h210401".
FormList = {form_list, [{"IHTX_F_10_00_00_00_00_H210401",true},
{"IHTX_F_09_00_00_00_00_H210401",true},
{"IHTX_F_11_11_02_02_01_H220401",true},
{"IHTX_F_03_00_00_00_00_H210401",false},
{"IHTX_F_12_00_00_00_00_H211215",true},
{"IHTX_F_07_00_00_00_00_H210401",true},
{"IHTX_F_15_00_00_00_00_H210401",false},
{"IHTX_F_11_00_00_00_00_H210401",false},
{"IHTX_F_02_00_00_00_00_H210401",true},
{"IHTX_F_01_00_00_00_00_H240401",true}]}.
How to find CurrPageName from the FormList? I tried lists:keyfind, keysearch to the innerlist but always returning false or some error. If the CurrPageName exist and if its value is true then only it should return a true else false.
I'm newbie to erlang. Thanks
The list stores the page names as upper-case strings, so first make sure your CurrPageName variable contains upper-case string too
CurrPageName = string:to_upper("ihtx_f_10_00_00_00_00_h210401").
Then extract the list of tuples and search for the page
{form_list, L} = FormList, % Extract tuple list to L
KeyPosition=1, % The name we look for is at position 1 in the tuple
T=lists:keyfind(CurrPageName, KeyPosition, L),
case T of
{_Key, true} ->
true ;
false ->
false
end.
you can use proplists.
CurrPageName = string:to_upper("ihtx_f_10_00_00_00_00_h210401").
{form_list, L} = FormList,
Res = proplists:is_defined(CurrPageName, L)
Related
I have stumbled upon this line of code and I am not sure what the [ ? ] part represents (my guess is it's a sort of a wildcard but I searched it for a while and couldn't find anything):
['?'] = function() return is_canadian and "eh" or "" end
I understand that RHS is a functional ternary operator. I am curious about the LHS and what it actually is.
Edit: reference (2nd example):
http://lua-users.org/wiki/SwitchStatement
Actually, it is quite simple.
local t = {
a = "aah",
b = "bee",
c = "see",
It maps each letter to a sound pronunciation. Here, a need to be pronounced aah and b need to be pronounced bee and so on. Some letters have a different pronunciation if in american english or canadian english. So not every letter can be mapped to a single sound.
z = function() return is_canadian and "zed" or "zee" end,
['?'] = function() return is_canadian and "eh" or "" end
In the mapping, the letter z and the letter ? have a different prononciation in american english or canadian english. When the program will try to get the prononciation of '?', it will calls a function to check whether the user want to use canadian english or another english and the function will returns either zed or zee.
Finally, the 2 following notations have the same meaning:
local t1 = {
a = "aah",
b = "bee",
["?"] = "bee"
}
local t2 = {
["a"] = "aah",
["b"] = "bee",
["?"] = "bee"
}
If you look closely at the code linked in the question, you'll see that this line is part of a table constructor (the part inside {}). It is not a full statement on its own. As mentioned in the comments, it would be a syntax error outside of a table constructor. ['?'] is simply a string key.
The other posts alreay explained what that code does, so let me explain why it needs to be written that way.
['?'] = function() return is_canadian and "eh" or "" end is embedded in {}
It is part of a table constructor and assigns a function value to the string key '?'
local tbl = {a = 1} is syntactic sugar for local tbl = {['a'] = 1} or
local tbl = {}
tbl['a'] = 1
String keys that allow that convenient syntax must follow Lua's lexical conventions and hence may only contain letters, digits and underscore. They must not start with a digit.
So local a = {? = 1} is not possible. It will cause a syntax error unexpected symbol near '?' Therefor you have to explicitly provide a string value in square brackets as in local a = {['?'] = 1}
they gave each table element its own line
local a = {
1,
2,
3
}
This greatly improves readability for long table elements or very long tables and allows you maintain a maximum line length.
You'll agree that
local tbl = {
z = function() return is_canadian and "zed" or "zee" end,
['?'] = function() return is_canadian and "eh" or "" end
}
looks a lot cleaner than
local tbl = {z = function() return is_canadian and "zed" or "zee" end,['?'] = function() return is_canadian and "eh" or "" end}
I'm trying to iterate through a table with a variable amount of elements and get all possible combinations, only using every element one time. I've landed on the solution below.
arr = {"a","b","c","d","e","f"}
function tablelen(table)
local count = 0
for _ in pairs(table) do
count = count + 1
end
return count
end
function spellsub(table,start,offset)
local str = table[start]
for i = start+offset, (tablelen(table)+1)-(start+offset) do
str = str..","..table[i+1]
end
return str
end
print(spellsub(arr,1,2)) -- Outputs: "a,d,e" correctly
print(spellsub(arr,2,2)) -- Outputs: "b" supposed to be "b,e,f"
I'm still missing some further functions, but I'm getting stuck with my current code. What is it that I'm missing? It prints correctly the first time but not the second?
A solution with a coroutine iterator called recursively:
local wrap, yield = coroutine.wrap, coroutine.yield
-- This function clones the array t and appends the item new to it.
local function append (t, new)
local clone = {}
for _, item in ipairs (t) do
clone [#clone + 1] = item
end
clone [#clone + 1] = new
return clone
end
--[[
Yields combinations of non-repeating items of tbl.
tbl is the source of items,
sub is a combination of items that all yielded combination ought to contain,
min it the minimum key of items that can be added to yielded combinations.
--]]
local function unique_combinations (tbl, sub, min)
sub = sub or {}
min = min or 1
return wrap (function ()
if #sub > 0 then
yield (sub) -- yield short combination.
end
if #sub < #tbl then
for i = min, #tbl do -- iterate over longer combinations.
for combo in unique_combinations (tbl, append (sub, tbl [i]), i + 1) do
yield (combo)
end
end
end
end)
end
for combo in unique_combinations {'a', 'b', 'c', 'd', 'e', 'f'} do
print (table.concat (combo, ', '))
end
For a tables with consecutive integer keys starting at 1 like yours you can simply use the length operator #. Your tablelen function is superfluous.
Using table as a local variable name shadows Lua's table library. I suggest you use tbl or some other name that does not prevent you from using table's methods.
The issue with your code can be solved by printing some values for debugging:
local arr = {"a","b","c","d","e","f"}
function spellsub(tbl,start,offset)
local str = tbl[start]
print("first str:", str)
print(string.format("loop from %d to %d", start+offset, #tbl+1-(start+offset)))
for i = start+offset, (#tbl+1)-(start+offset) do
print(string.format("tbl[%d]: %s", i+1, tbl[i+1]))
str = str..","..tbl[i+1]
end
return str
end
print(spellsub(arr,1,2)) -- Outputs: "a,d,e" correctly
print(spellsub(arr,2,2)) -- Outputs: "b" supposed to be "b,e,f"
prints:
first str: a
loop from 3 to 4
tbl[4]: d
tbl[5]: e
a,d,e
first str: b
loop from 4 to 3
b
As you see your second loop does not ran as the start value is already greater than the limit value. Hence you only print the first value b
I don't understand how your code is related to what you want to achieve so I'll leave it up to you to fix it.
I query the list of users from Mnesia Database in Chicagoboss. I'm getting the error when I try to add the Lists within lists:foreach with ++ operator. My aim is, based on userid I will do ets:lookup to my cache and create a List like - [{{<<"name">>,<<"Batman">>}, {<<"steps">>,2552}, {<<"distance">>,2050}}].
For each user I'll create this list and add with the previous List. So that ultimately I can can sort on <<"steps">> and convert the binary list by json encoding and send it to the client via Websockets.
I'm getting the error at this line:
Reading1 = Reading2 ++ Currentlist
as I've decalred Reading1 as an Empty list.
My question is how can I manipulate the lists within the lists:foreach and then send the result List via websocket?
BelugaUsers = boss_db:find(users, [{accesstoken, 'not_equals', ''}]),
Reading1 = [],
Reading2 = [],
lists:foreach(fun(X) ->
{_,_,BEmail,BName,_,_,BAccessToken,_} = X,
UserKey = BEmail ++ "-" ++ ?MYAPICALL1,
io:format("UserKey for Leader Board: ~n~p~n",[UserKey]),
[Reading] = ets:lookup(myapi_cache, list_to_binary(UserKey)),
{_,Result} = Reading,
ActivitySummary = proplists:get_value(<<"activitySummary">>, Result),
%Print ActivitySummary for the user ....printing fine
io:format("ActivitySummary ==========: ~n~p~n",[ActivitySummary]),
%Create a list of the format
%[{{<<"name">>,<<"Batman">>}, {<<"steps">>,2552}, {<<"distance">>,2050}}]
Currentlist = [{{<<"name">>, list_to_binary(BName)}, {<<"steps">>, proplists:get_value(<<"steps">>, ActivitySummary)}, {<<"distance">>, proplists:get_value(<<"distance">>, ActivitySummary)}}],
%% HERE I'M GETTING error%%
Reading1 = Reading2 ++ Currentlist
end, BelugaUsers),
%sort the list
Reading3 = lists:keysort(2, Reading1),
%reverse the list
Reading4 = lists:reverse(Reading3),
WebSocketId ! {text, jsx:encode(Reading4)},
Erlang variables are single-assignment; once bound to a value, they can't be re-bound to a different value.
The lists:foreach/2 function is not useful for this problem because it can't create a new value and return it to its caller. You should instead use lists:map/2, perhaps like this:
BelugaUsers = boss_db:find(users, [{accesstoken, 'not_equals', ''}]),
Reading = lists:map(
fun(X) ->
{_,_,BEmail,BName,_,_,BAccessToken,_} = X,
UserKey = BEmail ++ "-" ++ ?MYAPICALL1,
io:format("UserKey for Leader Board: ~n~p~n",[UserKey]),
{_,Result} = hd(ets:lookup(myapi_cache, list_to_binary(UserKey))),
ActivitySummary = proplists:get_value(<<"activitySummary">>, Result),
%%Print ActivitySummary for the user ....printing fine
io:format("ActivitySummary ==========: ~n~p~n",[ActivitySummary]),
%%Create a tuple of the format
%%{{<<"name">>,<<"Batman">>}, {<<"steps">>,2552}, {<<"distance">>,2050}}
{{<<"name">>, list_to_binary(BName)},
{<<"steps">>, proplists:get_value(<<"steps">>, ActivitySummary)},
{<<"distance">>, proplists:get_value(<<"distance">>, ActivitySummary)}}
end, BelugaUsers),
%%sort the list
Reading2 = lists:keysort(2, Reading),
%%reverse the list
Reading3 = lists:reverse(Reading2),
WebSocketId ! {text, jsx:encode(Reading3)}.
The lists:map/2 function applies a function to each value in a list to a produce a potentially different value and returns a new list consisting of those new values. This is essentially what you were trying to do with lists:foreach/2 and your attempt to use imperative assignment to add each element to an already-existing list.
You could alternatively use a list comprehension but I think lists:map/2 is clearer in this situation.
Hello I am using Node4j and I am trying to change de properties of a relationship depending of it´s type , the code that I have is :
Start f=rel(1) MATCH ()-[f]->()
SET f.distancia=256
return CASE f
WHEN rel(f)='FERROCARRIL'
THEN SET f.tiempo=f.distancia/150*60, f.precio=f.distancia*0.23
WHEN rel(f)='AVION'
THEN SET f.tiempo=f.distancia/250*60, f.precio=f.distancia*0.6
WHEN rel(f)='BUS'
THEN SET f.tiempo=f.distancia/110*60, f.precio=f.distancia*0.25
ELSE
SET f.tiempo=f.distancia/100*60, f.precio=f.distancia*0.28
END
I also try putting in the case rel(f) instead of f but i obtained the same result.
It returns an invalid syntax error, how I can do this ?
PS: I need to obtain f by the id of the relationship
It doesn't work because you can't set values in a CASE statement. To make it work you have to set the values in a FOREACH statement. So, in your CASE statement you can set an empty array for types that do not match and set a single item array for the one type that does match.
MATCH ()-[f]->()
WHERE id(f) = 1
SET f.distancia=256
WITH f
, CASE type(f)
WHEN 'FERROCARRIL'
THEN [[1],[],[],[]]
WHEN 'AVION'
THEN [[],[1],[],[]]
WHEN 'BUS'
THEN [[],[],[1],[]]
ELSE
[[],[],[],[1]]
END as type_rel
FOREACH( x in type_rel[0] | SET f.tiempo=f.distancia/150*60, f.precio=f.distancia*0.23 )
FOREACH( x in type_rel[1] | SET f.tiempo=f.distancia/250*60, f.precio=f.distancia*0.6 )
FOREACH( x in type_rel[2] | SET f.tiempo=f.distancia/110*60, f.precio=f.distancia*0.25 )
FOREACH( x in type_rel[3] | SET f.tiempo=f.distancia/100*60, f.precio=f.distancia*0.28 )
RETURN type_rel, f
An alternate cleaner approach would be something like this...
MATCH ()-[f]->()
WHERE id(f) = 1
SET f.distancia=256
WITH f
, CASE type(f)
WHEN 'FERROCARRIL'
THEN [150, 0.23]
WHEN 'AVION'
THEN [250, 0.6]
WHEN 'BUS'
THEN [110, 0.25]
ELSE
[100, 0.28]
END as factors
SET f.tiempo=f.distancia/ factors[0] * 60, f.precio= f.distancia * factors[1]
RETURN f
I am starting to learn Lua from Programming in Lua (2nd edition)
I didn't understand the following in the book. Its very vaguely explained.
a.) w={x=0,y=0,label="console"}
b.) x={math.sin(0),math.sin(1),math.sin(2)}
c.) w[1]="another field"
d.) x.f=w
e.) print (w["x"])
f.) print (w[1])
g.) print x.f[1]
When I do print(w[1]) after a.), why doesn't it print x=0
What does c.) do?
What is the difference between e.) and print (w.x)?
What is the role of b.) and g.)?
You have to realize that this:
t = {3, 4, "eggplant"}
is the same as this:
t = {}
t[1] = 3
t[2] = 4
t[3] = "eggplant"
And that this:
t = {x = 0, y = 2}
is the same as this:
t = {}
t["x"] = 0
t["y"] = 2
Or this:
t = {}
t.x = 0
t.y = 2
In Lua, tables are not just lists, they are associative arrays.
When you print w[1], then what really matters is line c.) In fact, w[1] is not defined at all until line c.).
There is no difference between e.) and print (w.x).
b.) creates a new table named x which is separate from w.
d.) places a reference to w inside of x. (NOTE: It does not actually make a copy of w, just a reference. If you've ever worked with pointers, it's similar.)
g.) Can be broken up in two parts. First we get x.f which is just another way to refer to w because of line d.). Then we look up the first element of that table, which is "another field" because of line c.)
There's another way of creating keys in in-line table declarations.
x = {["1st key has spaces!"] = 1}
The advantage here is that you can have keys with spaces and any extended ASCII character.
In fact, a key can be literally anything, even an instanced object.
function Example()
--example function
end
x = {[Example] = "A function."}
Any variable or value or data can go into the square brackets to work as a key. The same goes with the value.
Practically, this can replace features like the in keyword in python, as you can index the table by values to check if they are there.
Getting a value at an undefined part of the table will not cause an error. It will just give you nil. The same goes for using undefined variables.
local w = {
--[1] = "another field"; -- will be set this value
--["1"] = nil; -- not save to this place, different with some other language
x = 0;
y = 0;
label = "console";
}
local x = {
math.sin(0);
math.sin(1);
math.sin(2);
}
w[1] = "another field" --
x.f = w
print (w["x"])
-- because x.f = w
-- x.f and w point one talbe address
-- so value of (x.f)[1] and w[1] and x.f[1] is equal
print (w[1])
print ((x.f)[1])
print (x.f[1])
-- print (x.f)[1] this not follows lua syntax
-- only a function's has one param and type of is a string
-- you can use print "xxxx"
-- so you print x.f[1] will occuur error
-- in table you can use any lua internal type 's value to be a key
-- just like
local t_key = {v=123}
local f_key = function () print("f123") end
local t = {}
t[t_key] = 1
t[f_key] = 2
-- then t' key actualy like use t_key/f_key 's handle
-- when you user t[{}] = 123,
-- value 123 related to this no name table {} 's handle