4
votes

I'm trying to write some Erlang that would filter an array in the form:

[{dakota, "cold and snowy"}, {california, "perfect weather"}] % and so on

Here is what I've got - I get a syntax error when I try to make a .beam from werl.

-module(matcher).
-export([findkeywords/2]).

findkeywords(Word, Arr) -> 
    IsMatch = fun({Key, Desc}) -> 
        lists:any(fun(X) -> X==Word end, string:tokens(Desc, " ")),
    lists:filter(IsMatch, [{K, V} || {K, V} <- Arr]).

Can anyone spot where my syntax is off?

4

4 Answers

6
votes

I saw your call to arms on twitter and just had to come take a look. :D

If you want this to compile, you're just missing an end on your fun on line 6. Add it in and it compiles without complaint.

-module(matcher).
-export([findkeywords/2]).

findkeywords(Word, Arr) -> 
    IsMatch = fun({Key, Desc}) -> 
        lists:any(fun(X) -> X==Word end, string:tokens(Desc, " ")) end, % ADD THE END HERE
    lists:filter(IsMatch, [{K, V} || {K, V} <- Arr]).

You can clean this up a bit too, unless this is an exercise in string matching for yourself. The string module has str(String, SubString) -> Index and rstr(String, SubString) -> Index that are described as such in the Erlang Manual:

Returns the position where the first/last occurrence of SubString begins in String. 0 is returned if SubString does not exist in String. For example:

> string:str(" Hello Hello World World ", "Hello World").
8 

Using this tidies it up a bit, and you could even shorten the whole thing into a one liner. The list comprehension is unnecessary as the data is already in the format that you're trying to feed it in.

-module(matcher).
-export([findkeywords/2]).

findkeywords(Word, Arr) -> 
    lists:filter(fun({_Key, Desc}) -> string:str(Desc, Word) > 0 end, Arr).
3
votes

You miss one "end" from the two functions. Also, it looks like the list comprehension in this example used is not needed.

2
votes
findkeywords(Word, Arr) -> 
    IsMatch =
    fun({_, Desc}) -> lists:any(fun(X) -> X == Word end, string:tokens(Desc, " ")) end,
    lists:filter(IsMatch, [{K, V} || {K, V} <- Arr]).
2
votes

You are missing the end key word for one of the funs. However, looks like you are searching within strings. This is normally what is use

-define(DATA,[{dakota, "cold and snowy"}, {california, "perfect weather"}]).
string_contains(Big,Small)-> string:rstr(Big,Small) > 0.
findkeywords(Word)-> [X || X <- ?DATA,string_contains(element(2,X),Word) == true].