Concatenate Map values when providing several keys

I’m on my learning curve of Elixir with Exercism.
I have a question I’m stuck with:

  • given an list of colors like colors = [:orange, :orange, :black]
  • and a color/value Map defined as follows:
@colors_map %{
    black: 0,
    brown: 1,
    red: 2,
    orange: 3,
    yellow: 4,
    green: 5,
    blue: 6,
    violet: 7,
    grey: 8,
    white: 9
  }

My first try was to iterate on the colors list and call Map.get/3 function:

Enum.each(colors, fn c -> Map.get(@colors_map, c) end)

But I’m stuck with how to concatenate the values extracted from the Map as a number resulting from the concatenation of the values for the first 2 list values only.
For example, for the colors = [:orange, :orange, :black], I’d like to get:
33 (what corresponds to twice 3 for the :orange key, `:black being the last value is dropped).

In short, I need to convert the provided list of colors to its numeric resistance value.

Update:
I alsotried this:

digits = Enum.take(colors, 2)
for x <- digits, do: Map.get(@colors_map, x)

This returns me a list [3, 3]. How is it possible to call join on the result list in case of the use of the comprehension?

Thank you.

2 Likes

Assign it to a variable. In Elixir, everything(?) is an expression. So you can assign to the result of a if, case, cond, for etc.

x =
  for a <- b do
    a + 1
  end

y = 
  if true do
    "T"
  else
    "F"
  end
1 Like

I don’t know if it is enough elegant solution, but here is what I came to:

digits = Enum.take(colors, 2)
result = for x <- digits, do: Map.get(@colors_map, x)
Enum.join(result)

what returns “33” for colors = [:orange, :orange, :black] :slight_smile:

1 Like
for d <- Enum.take(colors, 2), into: "", do: to_string(@colors_map[d])
3 Likes

There’s Enum.drop(colors, -1) to drop the last color instead of hardcoding taking 2.

3 Likes

you want something like this?

@color_map
|> Map.take(colors)
|> Map.values()
|> Enum.join()

edit:
oh, it needs to be in the same order from the list, so it would be something like this:

colors
|> Enum.map(& @colors_map[&1])
|> Enum.join()
1 Like

@cevado you need to drop the last item in the list as @LostKobrakai mentioned.

colors
|> Enum.drop(-1)
|> Enum.map(fn colour -> Map.fetch!(@colors_map, colour) end)
|> Enum.join()