sams
sams

Reputation: 188

Elixir getting values that are not empty in a map

Given a map like this:

mapOne = %{"dog" => "foo", "cat" => "", "name" => "generic","fizz" => "", }

How would you get just the keys of the values which are empty into a list? ["cat", "fizz"]

It seems that Enum.filter is returning a list of key, value pairs rather than just the list

mapOne |> Enum.filter(fn {k,v} -> if v == "" do k end end) [{"cat", ""}, {"fizz", ""}]

Thanks!

Upvotes: 2

Views: 2510

Answers (3)

Mike Buhot
Mike Buhot

Reputation: 4885

Comprehensions work well for this case:

iex(1)> mapOne = %{"dog" => "foo", "cat" => "", "name" => "generic","fizz" => "", }

iex(2)> for {k, v} <- mapOne, v == "", do: k

["cat", "fizz"]

Upvotes: 6

Aetherus
Aetherus

Reputation: 8898

Enum.reduce(mapOne, [], fn
  ({k, ""}, acc) -> [k | acc]
  ({k, _v}, acc) -> acc
end)

This returns a list with reversed order than the previous answer, but the key order of a map means nothing anyway.

Upvotes: 1

Aetherus
Aetherus

Reputation: 8898

mapOne = %{"dog" => "foo", "cat" => "", "name" => "generic","fizz" => "", }

mapOne
|> Enum.filter(fn{_k, v}-> v == "" end)
|> Enum.map(fn{k, _v}-> k end)

By the way, Enum.filter/2 takes the items in the original list/map that make the anonymous function return truthy value (i.e. not false and not nil).

Your anonymous function

fn {k,v} -> if v == "" do k end end

returns nil (which is falsey) when v is not empty, and k (which is a string thus always truthy) when v is empty.

Upvotes: 0

Related Questions