lib for developers : libAssoc - primer - 09-17-2017 04:09 PM
Hello,
here is a library about list processing,
it add the Associative list concept.
What is "Associative list" ?
It's powerfull list that you can reach item by a key instead of an index.
You can store value based on name, for example list of GDP per country name...
This feature is well known in php, here is an example of php associated list :
PHP Code:
$mylist= ['key1'=>value1, 'otherkey'=>value2]; $mylist['key1'] // returns values1
With LibAssoc, it gives :
mylist:=AL_NEW(); //create the AList object
AL_SET(mylist,"key1",value1); //insert first value, for "key1" name
AL_SET(mylist,"key2",value2);
AL_GET(mylist,"key1"); // returns value1
Please note as Associative List is not a buildin object, most of API functions require the AList object to be passed as first parameter.
Note that 3 first lines can be shortened by this :
Code:
mylist:=AL_SPLIT("key1=value1;key2=value2",";","=");
Please note this lib has one dependency : LibList, please first download it.
Download LibAssoc v0.801 - sept 2017:
[attachment=5194]
API list : AL_NEW, AL_SET, AL_GET, AL_FKEY, AL_SIZE, AL_DEL, AL_VMATCH, AL_VMAP, AL_FOREACH, AL_SPLIT
AL_NEW()
Create a new Associative List
ex :
AL_SET(AList,Key,Val)
set/insert key+value in AList
AList is an associtive list,
Key is a string,
Val any type you want.
ex :
Code:
L:=AL_NEW();
AL_SET(L,"key1","value1");
AL_SET(L,"key2",123); // key2 value is 123.
AL_GET(AList,Key)
Return value from a given Key
if not found, return an empty string.
ex :
Code:
V:=AL_GET(L,"key1");
AL_FKEY(AList,Key)
is Key exist on AList ?
return non null if exist, 0 if not
ex :
Code:
if AL_FKEY(L,"key1") then ...
AL_SIZE(AList)
Returns the number of item
ex :
Code:
PRINT("there are "+AL_SIZE(L)+" item(s) ");
AL_DEL(AList,Key)
Remove an item from a Associative List
ex :
AL_VMATCH(AList,FCT)
Value Matching
Run a user function Fct on each items, based upon function return, build a subset Assciative List and return it.
user function receive item value, and must return >0 to match.
ex :
Code:
L:=AL_NEW();
AL_SET(L,"key1",10);
AL_SET(L,"key2",20);
EXPORT myFct(val)
IF val>15 return 1; END;
return 0;
END;
L2:=AL_VMATCH(L,"myFct"); // L2 have only the key2 item. (value>15)
AL_VMAP(AList,Fct)
Run user fuction on each Value
AL_FOREACH(AList,Fct)
Run user fuction on each (Key,Value)
ex :
Code:
EXPORT display(k,v)
PRINT(k+" -> "+v);
END;
AL_FOREACH(L,"display");
AL_SPLIT(Str,Sep1,Sep2)
Build a AList from a string
Sep1 is object separator
Sep2 is the key/value separator.
ex :
Code:
L:=AL_SPLIT("key1=123|key2=456|key3=789","|","=");
RE: lib for developers : libAssoc - pier4r - 09-17-2017 04:51 PM
nice!
Would be possible to see the source code as well?
RE: lib for developers : libAssoc - primer - 09-17-2017 05:26 PM
(09-17-2017 04:51 PM)pier4r Wrote: nice!
Would be possible to see the source code as well?
Yes,
source code is poorly commented, you have it here :
Code:
// LibAssoc v0.801 - primer september 2017
#pragma mode( separator(.,;) integer(h32) )
// decl : Order List functions (OL_)
OL_SEEKI(L,V,S,E);
//find a location to add
EXPORT OL_FADD(L,V)
BEGIN
local s:= SIZE(L);
IF s==0 THEN RETURN 1; END;
RETURN OL_SEEKI(L,V,1,s);
END;
// find position from an ordered list, return 0 if not found
EXPORT OL_FIND(L,V)
BEGIN
local p:=OL_FADD(L,V);
IF p>SIZE(L) OR L(p)≠V THEN RETURN 0; END;
RETURN p;
END;
// internal function
OL_SEEKI(L,V,S,E)
BEGIN
IF S==E THEN
IF V>L(M) THEN RETURN E+1; END;
RETURN E;
END;
local M:=CEILING((S+E)/2);
IF V>L(M) THEN RETURN OL_SEEKI(L,V,M,E); END;
IF V==L(M) THEN RETURN M; END;
IF S+1==E THEN
IF V≤L(S) THEN RETURN S; END;
RETURN E;
END;
RETURN OL_SEEKI(L,V,S,M);
END;
//test with : OL_FADD({2,4,6,8,10}, 5)
//---------------------------
// Associated List
EXPORT AL_NEW()
BEGIN
RETURN {{},{}};
END;
EXPORT AL_SET(L,K,V)
BEGIN
local keys:=L_GET(L,1);
local vals:=L_GET(L,2);
local r:=AL_NEW();
local p:=OL_FADD(keys,K);
IF p≤SIZE(keys) AND keys(p)==K THEN // => modify
vals:=L_SET(vals,p,V);
r:=L_SET(r,1,keys);
r:=L_SET(r,2,vals);
RETURN r;
END;
keys:=L_INS(keys,p,K);
vals:=L_INS(vals,p,V);
r:=L_SET(r,1,keys);
r:=L_SET(r,2,vals);
RETURN r;
END;
// test :
//AL_SET(AL_NEW(), "k5", 111);
//AL_SET(Ans, "k1", 222);
//AL_SET(Ans, "k5", 999);
//search for a key, return 0 if not found, not 0 if found
EXPORT AL_FKEY(L,K)
BEGIN
RETURN OL_FIND(L_GET(L,1),K);
END;
// return the value for the given key
EXPORT AL_GET(L,K)
BEGIN
local p:=AL_FKEY(L,K);
if p==0 THEN RETURN ""; END; // no value
RETURN L_GET(L_GET(L,2),p);
END;
// return size of the AL
EXPORT AL_SIZE(L)
BEGIN
RETURN SIZE(L_GET(L,1));
END;
// remove a key from an AL
EXPORT AL_DEL(L,K)
BEGIN
local n:=AL_SIZE(L);
IF n==0 THEN RETURN L; END;
local p:=AL_FKEY(L,K);
IF p==0 THEN RETURN L; END;
local keys:=L_GET(L,1);
local vals:=L_GET(L,2);
local r:=AL_NEW();
local k2:={}, v2:={},i;
FOR i FROM 1 TO n DO
if i≠p THEN
k2:=L_INS(k2,0,keys(i));
v2:=L_INS(v2,0,vals(i));
END;
END;
r:=L_SET(r,1,k2);
r:=L_SET(r,2,v2);
RETURN r;
END;
//identify values that matchs conditions, return keys,
//a function is used to find if it match or not. return >0 for yes.
EXPORT AL_VMATCH(L,FCT)
BEGIN
local keys:=L_GET(L,1);
local n:=SIZE(keys);
IF n==0 THEN RETURN {}; END;
local vals:=L_GET(L,2);
local ret:=L_MAP(vals,FCT);
local r:={},i;
FOR i FROM 1 TO n DO
IF ret(i)>0 THEN r:=L_INS(r,0,keys(i)); END;
END;
RETURN r;
END;
// test with
//EXPORT vtest(V) //do a test...
// BEGIN
// if SIZE(V)>2 THEN RETURN 1; END;
// RETURN 0;
// END;
// AL_VMATCH({{"k1","k2","k3"},{"a","abc","abcdef"}},"vtest")
EXPORT AL_VMAP(L,FCT)
BEGIN
local keys:=L_GET(L,1);
local n:=SIZE(keys);
IF n==0 THEN RETURN L; END;
local vals:=L_GET(L,2);
local ret:=L_MAP(vals,FCT);
local r:={keys, ARR2LST(ret)};
RETURN r;
//r:= ARR2LST(ret);
END;
// AL_VMAP({{"k1","k2","k3"},{"a","abc","abcdef"}},"vtest")
EXPORT AL_FOREACH(L,FCT)
BEGIN
local keys:=L_GET(L,1);
local n:=SIZE(keys);
local vals:=L_GET(L,2);
local k,v,f,i;
FOR i FROM 1 TO n DO
k:=L_GET(keys,i);
v:=L_GET(vals,i);
IF TYPE(k)==2 THEN k:="\""+k+"\""; END;
IF TYPE(v)==2 THEN v:="\""+v+"\""; END;
f:=FCT+"("+k+","+v+")";
EVAL(EXPR(f));
END;
END;
// test with
//EXPORT disp_al(a,b)
//BEGIN
//PRINT(a+" -> "+b);
//END;
// AL_FOREACH({{1,"a"},{"test",456}},"disp_al");
EXPORT AL_SPLIT(ST,s1,k)
BEGIN
local l1:=SPLIT(ST,s1),l2;
local r:=AL_NEW();
local i,n:=SIZE(l1);
local itm:="";
FOR i FROM 1 TO n DO
itm:=L_GET(l1,i);
l2:=SPLIT(itm,k);
r:=AL_SET(r, L_GET(l2,1),L_GET(l2,2));
END;
RETURN r;
END;
// AL_SPLIT("A=123!B=abc", "!","=") : split to AL
// AL_SPLIT2("A=1,2,3!B=4,abc", "!","=",",") : split to AL with a list as values
EXPORT AL_SPLIT2(ST,s1,k,s2)
BEGIN
local l1:=SPLIT(ST,s1),l2;
local r:=AL_NEW();
local i,n:=SIZE(l1);
local itm:="";
FOR i FROM 1 TO n DO
itm:=L_GET(l1,i);
l2:=SPLIT(itm,k);
r:=AL_SET(r, L_GET(l2,1),SPLIT(L_GET(l2,2),s2));
END;
RETURN r;
END;
RE: lib for developers : libAssoc - Marcos Cabral - 11-10-2020 01:18 PM
Hello people,
I found the key/value list a very important resource.
Some time ago, I was looking for a solution to save the values of some variables of a program, to be used in future executions of the same program, or of other programs.
I tried to use LibAssoc, but I'm not getting it right.
Both LibList and LibAssoc are installed on the calculator. I tried to use the L1 list as well as a list previously created by me. Does not work. Does anyone know what the reason is?
//Test use of LibAssoc
//Marcos Cabral
[/code]LibList();
LibAssoc();
display();
EXPORT TESTE()
BEGIN
LOCAL Size, Position, Key, Value;
L1:=AL_NEW();
AL_SET(L1, "Q", 6.2);
AL_SET(L1, "V", 2.0);
AL_SET(L1, "Y", 0.80);
Size:=AL_SIZE(L1);
Position:= AL_FKEY(L1,"V");
Value:=AL_GET(L1,"V");
PRINT();
PRINT("Size=" + Size);
PRINT("Position=" + Position);
PRINT("Value=" + Value);
AL_FOREACH(L1, "display"); // show all entries in the list
END;
EXPORT display(k,v)
PRINT(k+" -> "+v);
END;
|