Danny Ellis Jr.
Danny Ellis Jr.

Reputation: 1706

Elixir find first matching element in two lists

I am fairly new to Elixir, and I have a small business problem. I am trying to localize data returned in an api call to my Phoenix middle tier. I am getting the user's browser languages and parsing those into a list. The order of the languages is relevant. I want to find the first matching language from the browser language list in my list of supported languages.

I could do this with nested loops and all that, but this seems like something Elixir could do more elegantly.

Upvotes: 1

Views: 1621

Answers (2)

7stud
7stud

Reputation: 48599

Convert your supported langs into a set:

supported_langs = ["a", "b", "c"]
user_langs = ["z", "s", "b", "a"]

supported_langs_set = supported_langs |> Enum.into(MapSet.new)

Enum.find(user_langs, fn user_lang ->
  MapSet.member? supported_langs_set, user_lang
end)

Looking up something in a set is fast v. traversing a supported_langs list over and over again looking for each user_lang. However, if your lists are only a few elements long, it's not going to make much difference.

Upvotes: 0

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Use Enum.find/3:

user = ~w|ge es it|
supported = ~w|it ru en|

Enum.find(user, 'en', fn l -> Enum.empty?([l] -- supported) end)

Here 'en' is the default language to be returned as no matched were found. [l] -- supported (list distraction) would return [l] if there is no matches and [] if l exists in supported.

Or, alternatively, use nested Enum.find/3]:

Enum.find(user, 'en', fn l -> Enum.find(supported, & &1 == l) end)

Upvotes: 3

Related Questions