I'm new to Erlang and am trying to convert something like the following to a dict:
{struct,[{<<"1">>,<<"2,3,4">>},{<<"2">>,<<"2,3,4">>}]}
I'm getting this after decoding the following json using mochijson2:
<<"{"1":"2,3,4","2":"2,3,4"}">>
The final result I'm looking for would be something like:
1 -> [2,3,4]
2 -> [2,3,4]
I think it's a proplist but not sure how to proceed with the conversion. Thanks
I'm not sure what you are asking for but this is may be it:
1> Term = {struct,[{<<"1">>,<<"2,3,4">>},{<<"2">>,<<"2,3,4">>}]}.
{struct,[{<<"1">>,<<"2,3,4">>},{<<"2">>,<<"2,3,4">>}]}
2> {struct, PropList} = Term.
{struct,[{<<"1">>,<<"2,3,4">>},{<<"2">>,<<"2,3,4">>}]}
3> Dict = dict:from_list(PropList).
{dict,2,16,16,8,80,48,
{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
{{[],[],[],[],[],[],[],[],[],[],[],
[[<<"2">>|<<"2,3,4">>]],
[],[],
[[<<"1">>|<<"2,3,"...>>]],
[]}}}
4> dict:fetch_keys(Dict).
[<<"2">>,<<"1">>]
5> dict:fetch(<<"1">>, Dict).
<<"2,3,4">>
Related
I am learning Erlang and how to work with lists but I have a problem. I am making a program with the use of solving math problems for example Tot = X*Y*Z.
First I give in a variable to set the amount of problems I want to solve like this:
inTestes(Tests) ->AmountOfTests = Tests.
Now to hold my different variables I also made a record: -record(specs,{x,y,z}). that holds a tuplet with the 3 variables.
I try to fill this tuplet: inSpecs(X,Y,Z)-> #specs =[x=X,y=Y,z=Z]. But this doesn't work.
I think I need to use something like lists:append(The variables here)->#specs{x=X,y=Y,z=Z} but I just don't seem to get it right.
When I just do inSpecs(X,Y,Z)-> Specs =[X,Y,Z]. I get 1 list for example [10,20,30]
How can I hold multiple lists like this according to the AmountOfTests?
Could someone give me some guidance?
I try to fill this tuplet:
inSpecs(X,Y,Z)-> #specs =[x=X,y=Y,z=Z].
But this doesn't work
And why do you think that should work? Do you think the following should work to create a list:
MyList = ! 3, 4; 5].
Computer programming requires exact syntax--not 5 out of 7 characters that are correct.
Please point to any book, website, or documentation that says that you can create a record with this syntax:
#specs =[x=X,y=Y,z=Z].
Here's what you can do:
-module(my).
-compile(export_all).
-record(specs, {x,y,z}).
inSpecs(X,Y,Z)-> #specs{x=X,y=Y,z=Z}.
In the shell:
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> Record = my:inSpecs(10, 20, 30).
{specs,10,20,30}
3> rr("my.erl").
[specs]
4> Record.
#specs{x = 10,y = 20,z = 30}
5> Record#specs.x.
10
When I just do inSpecs(X,Y,Z)-> Specs =[X,Y,Z]. I get 1 list for
example [10,20,30]
How can I hold multiple lists like this according to the
AmountOfTests?
Suppose AmountOfTests is equal to 3, what should inSpecs/3 return?
Response to comment:
Here's how you can create three specs with the same data:
-module(my).
-compile(export_all).
-record(specs, {x,y,z}).
inSpecs(X,Y,Z)-> #specs{x=X,y=Y,z=Z}.
create_specs(0) -> [];
create_specs(N) -> [inSpecs(1,2,3) | create_specs(N-1)].
In the shell:
1> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
2> rr(my).
[specs]
3> Specs = my:create_specs(3).
[#specs{x = 1,y = 2,z = 3},
#specs{x = 1,y = 2,z = 3},
#specs{x = 1,y = 2,z = 3}]
Or, if you have the data for the specs in a list like this:
SpecData = [ [1,2,3], [12,13,14], [7,8,9] ].
Then you can create a function like this:
-module(my).
-compile(export_all).
-record(specs, {x,y,z}).
inSpecs(X,Y,Z)-> #specs{x=X,y=Y,z=Z}.
create_specs([]) -> [];
create_specs([ [X,Y,Z] | Tail]) ->
[inSpecs(X,Y,Z) | create_specs(Tail)].
In the shell:
17> f().
ok
18> c(my).
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}
19> SpecData = [ [1,2,3], [12,13,14], [7,8,9] ].
[[1,2,3],[12,13,14],[7,8,9]]
20> Specs = my:create_specs(SpecData).
[#specs{x = 1,y = 2,z = 3},
#specs{x = 12,y = 13,z = 14},
#specs{x = 7,y = 8,z = 9}]
It seems like you're trying to get the 3 values from your list and put them in your record. You can do that with pattern matching. If you know the list you are being sent has exactly 3 values in it, you can do it with the following:
inTests( [X, Y, Z] ) ->
#specs{ x = X, y = Y, z = Z}.
I have credit card number, let's say 5940043543536. And for security purposes I only want to display the first four digits.
How would one do that in erlang?
A string in Erlang is just a list of integers, so you can use lists:sublist/3:
1> String = "5940043543536".
"5940043543536"
2> lists:sublist(String, 1, 4).
"5940"
Note that the position argument starts from 1 and not 0.
In case you are receiving binary (instead of string)
binary:part(<<"123455678901234">>, 1, 4).
<<"2345">>
or if you need get last four digits
binary:part(<<"123455678901234">>, {byte_size(<<"123455678901234">>), -4}).
<<"1234">>
newer versions of Erlang have built in string functions. For your case
1> string:slice("123455678901234", 1, 4).
"1234"
there is a string:substring function too, which works the same way, but it has been depreciated for slice.
You can try use pattern matching:
1> String = "5940043543536".
"5940043543536"
2> [A,B,C,D|_] = String.
"5940043543536"
3> [A,B,C,D].
"5940"
Or you can create your own function, eg:
1> String = "5940043543536".
"5940043543536"
2> GetDigits = fun F(_, Acc, 0) -> lists:reverse(Acc);
F([H|T], Acc, N) -> F(T, [H|Acc], N - 1) end.
#Fun<erl_eval.43.91303403>
3> GetDigits(String, [], 4).
"5940"
I have a list like List = [{0,12},{0,12},{-1,0},{0,12},{0,4},{1,2}] and a string Str = "https://www.youtube.com/watch?v=WQfdwsPao9E", now I've to find all the substrings using start and end point from list.
I want substrings to be returned in a List like ["https://www","https://www",..]
I tried using this:
C=lists:map(fun({X,Y}) -> string:sub_string(Str,X,Y) end,List)
1> List = [{0,12},{0,12},{-1,0},{0,12},{0,4},{1,2}].
[{0,12},{0,12},{-1,0},{0,12},{0,4},{1,2}]
2> Str = "https://www.youtube.com/watch?v=WQfdwsPao9E".
"https://www.youtube.com/watch?v=WQfdwsPao9E"
3> Len = length(Str).
43
4> [string:sub_string(Str,max(1,X),min(Len,Y)) || {X,Y} <- List].
["https://www.","https://www.",[],"https://www.","http",
"ht"]
5>
you may have to adjust the indexes in the string to fit exactly to your need.
[edit] It looks like I didn't interpret correctly what is the meaning of the tuple. I think it is {Fist_Char_Index, Char_Number}, or {-1,0} if no match is found. So you should use:
[string:sub_string(Str,X+1,X+Y) || {X,Y} <- List, {X,Y} =/= {-1,0}].
I am having Data like the below:
Data = [{<<"status">>,<<"success">>},
{<<"META">>,
{struct,[{<<"createdat">>,1406895903.0},
{<<"user_email">>,<<"gopikrishnajonnada#gmail.com">>},
{<<"campaign">>,<<"5IVUPHE42HP1NEYvKb7qSvpX2Cm">>}]}},
{<<"mode">>,1}]
And Now i am having a
FieldList = ['<<"5IVUPHE42HP1NEYvKb7qSvpX2Cm">>']
Now:
I am trying like the below but i am getting empty instead of the value
90> [L || L <- FieldList,proplists:get_value(<<"campaign">>,element(2,proplists:get_value(<<"META">>,Data,{[],[]}))) == L].
[]
so how to get the both values are equal and get the final value.
You can parse the atom as if it were an Erlang term:
atom_to_binary(Atom) ->
L = atom_to_list(Atom),
{ok, Tokens, _} = erl_scan:string(L ++ "."),
{ok, Result} = erl_parse:parse_term(Tokens),
Result.
You can then do
[L ||
L <- FieldList,
proplists:get_value(<<"campaign">>,
element(2,
proplists:get_value(<<"META">>,Data,{[],[]})))
== atom_to_binary(L)
].
You can also do it the other way round, (trying to) convert the binary to an atom using this function:
binary_literal_to_atom(Binary) ->
Literal = lists:flatten(io_lib:format("~p", [Binary])),
try
list_to_existing_atom(Literal)
catch
error:badarg -> undefined
end.
This function will return undefined if the atom is not known yet (s. Erlang: binary_to_atom filling up atom table space security issue for more information on this). This is fine here, since the match can only work if the atom was known before, in this case by being defined in the FieldList variable.
How did you get those values in the first place?
Data = [{<<"status">>,<<"success">>},
{<<"META">>,
{struct,[{<<"createdat">>,1406895903.0},
{<<"user_email">>,<<"gopikrishnajonnada#gmail.com">>},
{<<"campaign">>,<<"5IVUPHE42HP1NEYvKb7qSvpX2Cm">>}]
}
},
{<<"mode">>,1}].
[_,{_,{struct,InData}}|_] = Data.
[X || {<<"campaign">>,X} <- InData].
it gives you the result in the form : [<<"5IVUPHE42HP1NEYvKb7qSvpX2Cm">>]
of course you can use the same kind of code if the tuple {struct,InData} may be in a different place in the Data variable.
-module(wy).
-compile(export_all).
main() ->
Data = [{<<"status">>,<<"success">>},
{<<"META">>,
{struct,[{<<"createdat">>,1406895903.0},
{<<"user_email">>,<<"gopikrishnajonnada#gmail.com">>},
{<<"campaign">>,<<"5IVUPHE42HP1NEYvKb7qSvpX2Cm">>}]
}
},
{<<"mode">>,1}],
Fun = fun({<<"META">>, {struct, InData}}, Acc) ->
Value = proplists:get_value(<<"campaign">>, InData, []),
[Value | Acc];
(_Other, Acc)->
Acc
end,
lists:foldl(Fun, [], Data).
I think you can use this code.
How to convert this string format "{hari, localost}" into this: {"hari", "localost"}, in Erlang?
I tried to convert this format with lot of trial and error method, but I can't get the solution.
I guess you need to convert from string, so you can use the modules erl_scan and erl_parse:
1> erl_scan:string("{hari, localost}"++".").
{ok,[{'{',1},
{atom,1,hari},
{',',1},
{atom,1,localost},
{'}',1},
{dot,1}],
1}
2> {ok,Term} = erl_parse:parse_term(Tokens).
{ok,{hari,localost}}
3>Conv = fun({X, Y}) -> {atom_to_list(X), atom_to_list(Y)} end.
#Fun<erl_eval.6.80484245>
4> Conv(Term).
{"hari","localost"}
5>
Note 1 the function erl_parse:parse_term/1 will work only if Terms is a valid expression, it is why I had to add a "." at the end of the input.
Note 2 yo can directly transform to the final expression if you quote the terms in the input expression:
1> {ok,Tokens,_} = erl_scan:string("{\"hari\", \"localost\"}.").
{ok,[{'{',1},
{string,1,"hari"},
{',',1},
{string,1,"localost"},
{'}',1},
{dot,1}],
1}
2> {ok,Term} = erl_parse:parse_term(Tokens).
{ok,{"hari","localost"}}
3>