| Author |
Message |
< Erlang ~ Problem processing a list |
| brett hallett |
Posted: Mon Sep 03, 2007 12:16 pm |
|
|
|
User
Joined: 21 Aug 2007
Posts: 21
|
I'm trying to 'pop' entries off a list and print each one seperately,
but my attempts at printing abort when I try to output a single entry
in my print function.
Also how does one test for 'end-of-list' ??
Thanks,
Brett
================= test module ============
-module(numbers).
%% extract numerics from a mixed text line
%% eg "12cd 45erw 4rfr 22ss" => [12,45,4,22]
-export([ start/0 ]).
print( [L]) ->
[L1 | L ] = L,
io:format('~p~n', [L1]),
print(L);
print(0) -> ok.
start() ->
Txt ="098m 03 r9 f80239802389f0m9KDKLKLJDKLJm0983m890DMOm03 dlkfj3hljf4h3klhl 4j4 444 000044 rjhkrrkr34534539893 0390804980498409480 dkldjkl djkl djkl d00000002998",
io:format("~s ~n", [Txt]),
Txt2 = string:tokens(Txt," abcdefghijklmnopqysruvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
io:format("~p~n", [Txt2]),
print(Txt2).
==================== execution ==============
111> c(numbers.erl).
{ok,numbers}
112> numbers:start().
098m 03 r9 f80239802389f0m9KDKLKLJDKLJm0983m890DMOm03 dlkfj3hljf4h3klhl 4j4 444 000044 rjhkrrkr34534539893 0390804980498409480 dkldjkl djkl djkl d00000002998
["098",
"03",
"9",
"80239802389",
"0",
"9",
"0983",
"890",
"03",
"3",
"4",
"3",
"4",
"4",
"444",
"000044",
"34534539893",
"0390804980498409480",
"00000002998"]
=ERROR REPORT==== 3-Sep-2007::18:01:34 ===
Error in process <0.375.0> with exit value: {function_clause,[{numbers,print,[["098","03","9","80239802389","0","9","0983","890","03","3","4","3","4","4","444","000044","34534539893","0390804980498409480","00000002998"]]},{erl_eval,do_apply,5},{shell,exprs,6},{shell,eval_loop,3}]}
** exited: {function_clause,[{numbers,print,
[["098",
"03",
"9",
"80239802389",
"0",
"9",
"0983",
"890",
"03",
"3",
"4",
"3",
"4",
"4",
"444",
"000044",
"34534539893",
"0390804980498409480",
"00000002998"]]},
{erl_eval,do_apply,5},
{shell,exprs,6},
{shell,eval_loop,3}]} **
113> |
|
|
| Back to top |
|
| michal |
Posted: Mon Sep 03, 2007 1:12 pm |
|
|
|
User
Joined: 20 Jul 2006
Posts: 44
Location: London
|
Hi,
Rewrite function print as follows:
([L1 | L]) ->
io:format("~p~n", [L1]),
print(L);
print([]) ->
ok.
'end-of-list' in Erlang is noted as an empty list [].
Michal |
_________________ http://www.erlang-consulting.com |
|
| Back to top |
|
| Mazen |
Posted: Tue Sep 04, 2007 8:44 am |
|
|
|
User
Joined: 20 Jul 2006
Posts: 164
Location: London
|
Hi Brett,
a few pointers:
1) Lists are actually denoted as "lists in a list" where each list is actually a list of 2 elements.
E.g:[ 1, [] ]. and [1] is the same thing.
or
[ 1, [ 2, []]] is the same as [1,2].
note that [] is *not* the same as [ [] ].
knowing this you can patternmatch on then the second element in a list is empty i.e. [].
2) You can patternmatch directly in the function header and you should always try to do this as much as possible since it is very effective (this does not include function guards). As michal shows you in his code, you patternmatch on the first element of a list, and tail recurse on the second one.
thus you can type:
Code:
print([L1 | L]) ->
...
print(L);
print([]) ->
ok.
which means that you in the function head directly bind L1 to the first element of the list. Note that this will also match when ever the list only consists of 1 element as well.
The reason you get your error is because you are patternmatching on a list with *exactly* 1 element OR the integer 0, which makes the code fail because it can't find a suitable function to run according to you arguments.
For some bedtime reading see:
1) http://www.erlang.org/doc/reference_manual/data_types.html#2.10
2) http://www.erlang.org/doc/reference_manual/patterns.html#3
/Mazen |
|
|
| Back to top |
|
| brett hallett |
Posted: Wed Sep 05, 2007 4:15 am |
|
|
|
User
Joined: 21 Aug 2007
Posts: 21
|
Thanks for the responses - accurate AND useful
However now that I have a list thus
["999", "12", "345' ---etc ]
how do I convert this into a un-quoted list of integers ?
[ 999,12, 345, --- etc ].
I wish to sort the integer list , at the moment its a ascii list
and of course the sort order is not numeric sequence.
I've tried various "to_integer" functions to no avail. |
|
|
| Back to top |
|
| Mazen |
Posted: Wed Sep 05, 2007 8:16 am |
|
|
|
User
Joined: 20 Jul 2006
Posts: 164
Location: London
|
Not to serve you everything for "free", more fun if you find it yourself.
I suggest you take a look at the lists module in the documentation on how to traverse a list where you want to manipulate each element and/or order of the list.
Erlang have some built in functions to handle the type conversions. Take a look at the erlang module in the documentation and you will find functions that are called like "Something_to_Something" e.g. atom_to_list/1. This will, not very suprisingly convert an atom to a list.
Remember that a string in Erlang is defined as a list with acsii characters.
now you have everything you need to do what you wanted to do. Good luck! 
1) lists: http://www.erlang.org/doc/man/lists.html
2) erlang: http://www.erlang.org/doc/man/erlang.html |
|
|
| Back to top |
|
| brett hallett |
Posted: Thu Sep 06, 2007 11:42 pm |
|
|
|
User
Joined: 21 Aug 2007
Posts: 21
|
Actually I have read the manuals, even the one on list!
But as its such a poor manual, I did not understand the relevence
of map & zip in solving my problem.
Manuals without EXAMPLE code are less than useful. Smalltalk manuals
suffer from the same problem.
( I realise you did'nt write the manual
However, your comments did offer the hint required to suss out the answer, thanks.
Now I need to figure out Erlangs regexp facilities to replace the hidious "Txt2 =" line.
=====================================
-module(numbers3).
%% extract numerics from a mixed text line , sort ascending,
%% but retain any leading zeros.
%% based upon problem set by www.devx.com
%% eg "12cd 45erw 4rfr 22ss" => ["12","45","04","0022"]
%% then transform to [{4,"04"},{12,"12"},{22},{0022},{45,"45"}]
-export([ start/0 ]).
%% the print function 'pops' the head entry from the passed list
print( [ L1 | L]) ->
io:fwrite('~p~n', [L1]),
print(L);
print([]) -> ok.
start() ->
Txt =" 098m 03 r9 f8023982389f0m9KDKKLJm0983m890DMOm03 dlkfj3hljf4h3klhl 4j4 444 000044 rjhkrrkr34534539893 0390804980498409480 dkldjkl dj99kl djkl d00000002998",
io:fwrite("Txt : ~s ~n", [Txt]),
Txt2 = string:tokens(Txt," abcdefghijklmnopqysruvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
%% Txt2 will contain a list of numeric ("text") tokens
Txt3 = lists:map(fun(X) -> list_to_integer(X) end, Txt2),
%% Txt3 contains a list of numerics ( not text) tokens
Txt5 = lists:zip(Txt3, Txt2),
%% Txt5 contains a list of tuples [{12,"12"},{333,"333"}
Txt4 = lists:sort(Txt5),
%% Txt4 contains sorted tuple list
print(Txt4).
 |
|
|
| Back to top |
|
|
|
All times are GMT
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|