Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Elixir in action

elixir-in-action.livemd

Elixir in action

Streams

employees = ["Alice", "Bob", "John"]
Enum.with_index(employees)

Inefficient way:

employees
|> Enum.with_index()
|> Enum.each(fn {employees, index} ->
  IO.puts("#{index + 1}. #{employees}")
end)

Efficient way, Stream keeps stack the function until the list if finally traversed.

employees
|> Stream.with_index()
|> Enum.each(fn {employees, index} ->
  IO.puts("#{index + 1}. #{employees}")
end)

This example takes the input list and only prints the square root of elements representing a nonnegative number, adding an indexed prefix at the beginning:

[9, -1, "foo", 25, 49]
|> Stream.filter(&(is_number(&1) and &1 > 0))
|> Stream.map(&{&1, :math.sqrt(&1)})
|> Stream.with_index()
|> Enum.each(fn {{input, result}, index} ->
  IO.puts("#{index + 1}. sqrt(#{input}) = #{result}")
end)

The following function takes a filename and returns the list of all lines from that file that are longer than 80 characters:

defmodule Files do
  def large_lines!(path) do
    File.stream!(path)
    |> Stream.map(&String.trim_trailing(&1, "\n"))
    |> Enum.filter(&(String.length(&1) > 80))
  end

  def line_lengths!(path) do
    File.stream!(path)
    |> Stream.map(&String.trim_trailing(&1, "\n"))
    |> Enum.map(&String.length(&1))
  end

  def longest_line_lengths!(path) do
    File.stream!(path)
    |> Stream.map(&String.trim_trailing(&1, "\n"))
    |> Stream.map(&String.length(&1))
    |> Enum.max()
  end

  def longest_line!(path) do
    File.stream!(path)
    |> Stream.map(&String.trim_trailing(&1, "\n"))
    |> Enum.reduce(fn element, acc ->
      if String.length(element) > String.length(acc) do
        element
      else
        acc
      end
    end)
  end

  def word_per_line!(path) do
    File.stream!(path)
    |> Stream.map(&String.trim_trailing(&1, "\n"))
    |> Enum.map(&Enum.count(String.split(&1)))
  end
end
file = "./git/elixir-course/elixir-in-action.livemd"
Files.large_lines!(file)
Files.line_lengths!(file)
Files.longest_line_lengths!(file)
Files.longest_line!(file)