[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
end.
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).
BR,
Ulf W
Ulf Wiger, Co-founder & Developer Advocate, Feuerlabs Inc.
http://feuerlabs.com
-------------- 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