Samuel Pereira
Samuel Pereira

Reputation: 49

How to declare a piped list in a Enum inside another Enum?

I'm trying to use a piped list in a Enum inside another Enum. To try to make myself a little bit more clear, bellow is my code:

  def word_count(str) do
    String.downcase(str)
    |> String.split
    |> Enum.map(fn x -> Enum.count(LIST HERE, x) end)
  end

So what I want to do is to use the piped list as a parameter in the Enum.count

Upvotes: 0

Views: 173

Answers (2)

Adam Millerchip
Adam Millerchip

Reputation: 23091

The Enum functions take an enumerable as their first argument, so you can simply pipe a list into them.

If you want to count how many times each word appears, you can use Enum.frequencies/1:

def word_count(str) do
  str
  |> String.downcase()
  |> String.split()
  |> Enum.frequencies()
end

Example:

iex> Example.word_count("foo bar baz")                            
%{"bar" => 1, "baz" => 1, "foo" => 1}

In this case Enum.frequencies/1 was helpful, but often you can use Enum.reduce/3 to write your own logic. Here is Enum.frequencies/1 replaced with Enum.reduce/3 that does the same thing:

def word_count(str) do
  str
  |> String.downcase()
  |> String.split()
  |> Enum.reduce(%{}, fn word, acc ->
    Map.update(acc, word, 1, fn count -> count + 1 end)
  end)
end

In response to the comments, using Kernel.then/1, with the disclaimer that there is probably a better way to do this depending on what is desired (like reduce above, or using comprehensions):

1..10
|> then(fn one_to_ten ->
  Enum.map(one_to_ten, fn x ->
    Enum.map(one_to_ten, fn y ->
      {x, y}
    end)
  end)
end)

Upvotes: 2

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

If you are on the modern enough (as you should be,) then/2 is your friend.

"Foo bar foo"
|> String.downcase()
|> String.split()
|> then(&Enum.map(&1, fn x -> Enum.count(&1, fn y -> y == x end) end))
#⇒ [2, 1, 2]

The most readable solution would still be

words =
  "Foo bar foo"
  |> String.downcase()
  |> String.split()

Enum.map(words, &Enum.count(words, fn x -> x == &1 end))

One should not try to keep a single pipe despite readability.

Upvotes: 3

Related Questions