smaug
smaug

Reputation: 936

How to read a text file into a map in Erlang?

I have a text file like so:

{fruit, [apple,banana,kiwi]}.
{car, [estate,hatchback]}.
{tree, [ebony,pine,ask,birch]}.
{planet, [earth]}.

How can I read it into a map or any other data structure in Erlang (to further iterate over each key and its respective value) and finally print the map?

Upvotes: 2

Views: 520

Answers (2)

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26131

$ cat > things.txt
{fruit, [apple,banana,kiwi]}.
{car, [estate,hatchback]}.
{tree, [ebony,pine,ask,birch]}.
{planet, [earth]}.
$ erl
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V9.3  (abort with ^G)
1> {ok, L} = file:consult("things.txt").
{ok,[{fruit,[apple,banana,kiwi]},
     {car,[estate,hatchback]},
     {tree,[ebony,pine,ask,birch]},
     {planet,[earth]}]}
2> maps:from_list(L).
#{car => [estate,hatchback],
  fruit => [apple,banana,kiwi],
  planet => [earth],
  tree => [ebony,pine,ask,birch]}

Upvotes: 6

Eugen Dubrovin
Eugen Dubrovin

Reputation: 916

This one is works for me

-module(test). 
-export([start/0, scan_string/1]). 

start() -> 
   {ok, File} = file:open("Newfile.txt",[read]),
   {ok, List} = file:read(File,1024 * 1024),
   KeyVal = scan_string(List),

   F = fun({K,V}, Acc) -> maps:put(K, V, Acc) end,
   lists:foldl(F, #{}, KeyVal).

scan_string(TermString) ->
    {_, Strings} = lists:foldl(fun break_terms/2, {"", []}, TermString),
    Tokens = [T || {ok, T, _} <- lists:map(fun erl_scan:string/1, Strings)],
    AbsForms = [A || {ok, A} <- lists:map(fun erl_parse:parse_exprs/1, Tokens)],
    [V || {value, V, _} <- lists:map(fun eval_terms/1, AbsForms)].

break_terms($., {String, Lines}) ->
    Line = lists:reverse([$. | String]),
    {"", [Line | Lines]};
break_terms(Char, {String, Lines}) ->
    {[Char | String], Lines}.

eval_terms(Abstract) ->
    erl_eval:exprs(Abstract, erl_eval:new_bindings()).

Newfile.txt =

{fruit, [apple,banana,kiwi]}.
{car, [estate,hatchback]}.
{tree, [ebony,pine,ask,birch]}.
{planet, [earth]}.

Shell =

Eshell V9.3.1  (abort with ^G)
1> c(test).
{ok,test}
2> test:start().
#{car => [estate,hatchback],
  fruit => [apple,banana,kiwi],
  tree => [ebony,pine,ask,birch]}
3> 

Upvotes: 1

Related Questions