[erlang-questions] Additions to lists module
Richard O'Keefe
ok@REDACTED
Thu Nov 27 03:30:40 CET 2008
On 27 Nov 2008, at 12:52 pm, Michael McDaniel wrote:
>
> Everyone works on different kinds of problems and has their solutions.
> One immediate use I thought of follows.
>
> Note that html_tokenise is from Joe Armstrong's www_tools-1.0 on
> trapexit.
>
>
> {ok, H} = http:request("http://somewebsite.com") ,
> Ht = html_tokenise:string2toks( element(3, H) ) ,
> Pos = list_position:pos( Hal, {tagStart,"title"} ) ,
>
> {_, Title} = lists:nth( Pos+1, Hal ).
This is better as
{_,Title} = lists:after({tagStart,"title"}, Hal)
where
after(X, [X,Y|_]) -> Y;
after(X, [_|Ys]) -> after(X, Ys).
which does the job in one pass. The *order* and *adjacency*
of elements in a list often matters; the actual *positions*
far less often.
If we add
before(X, [Y,X|_]) -> Y;
before(X, [_|Ys]) -> before(X, Ys).
then we've matched the #after: and #before: methods in
ANSI Smalltalk's SequencedReadableCollection class.
If we add
after(X, [X,Y|_], _) -> Y;
after(X, [_|Ys], D) -> after(X, Ys, D);
after(_, [], D) -> D.
before(X, [Y,X|_], _) -> Y;
before(X, [_|Ys], D) -> before(X, Ys, D);
before(_, [], D) -> D.
then we've come close to matching the #after:ifAbsent:
and #before:ifAbsent: methods (which actually take funs
rather than default values).
Even simpler than after would be to adapt Lisp's (MEMBER - -)
function, and instead of returning false or true, return the
empty list or the place where the match was found. (Funny
how the Boolean anti-pattern keeps turning up, isn't it?)
Define
lmember(X, Xs = [X|_]) -> X;
lmember(X, [_ | Xs]) -> lmember(X, Xs);
lmember(_, []) -> [].
Then
[_,{_,Title}|_] = lmember({tagStart,"title"}, Hal)
and if we wanted to pick up the next two elements it would
be just as simple to do
[_,{_,Title},Next|_] = lmember({tagStart,"title"}, Hal)
More information about the erlang-questions
mailing list