[erlang-questions] How to return first {Key, Value} from Map where Predicate is true

Ulf Wiger ulf@REDACTED
Thu Jan 8 08:47:46 CET 2015

> On 08 Jan 2015, at 04:56, Harit Himanshu <harit.subscriptions@REDACTED> wrote:
> My attempt, looks like
> map_search_pred(Map, Pred)  ->
>   M = [{Key, Value} || {Key, Value} <- maps:to_list <maps:to_list>(Map), Pred(Key, Value) =:= true],
>   case length(M) of
>     0 -> {};
>     _ -> lists:nth(1, M)
>   end.
> Problem?
> The problem is efficiency.
> It uses list comprehension and runs for all the elements in the list. The better solution would be to return after the first match.
> As a beginner to language, I do not know a better idiomatic way to solve this, so looking for better ideas and suggestions

You can use 

map_search_pred(Map, Pred) ->
    case lists:dropwhile(fun(X) -> not Pred(X) end, maps:to_list <maps:to_list>(Map)) of
        [Found | _] -> Found;
        [] -> false

A few comments.

- Using {} as a return value denoting “not found” is unusual. My version mimicks lists:keyfind/2, which returns the matching object or ‘false’.

- Testing the length of the list using length/1 will force a count of all elements. In this case, you are only interested in checking if the list is non-empty, which is better done with a pattern-match. This also eliminates the need for calling lists:nth(1,M), which is also a more expensive option than hd(M).

Ulf W

Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150108/56d738f6/attachment.htm>

More information about the erlang-questions mailing list