Elixir – List vs Maps

In our last post, Getting Items from List with Elixir, we got values from a list and added them to new list. What if we wanted them as maps instead list? In this post, I'll show how to do both.

Option 1:

List of lists

list-vs-maps.test.ex

defmodule AccessLogAppTest do
  ...
  # filter_data
  test "filters data an array containing strings to match" do
    data = [
      ["a1", "TCP_HIT/200", "http://foo.bar/BARF/a/b/c/123456/somefile.mp4.ts"],
      ["a2", "TCP_HIT/206", "http://foo.bar/BARF/e/f/789012/someotherfile.mp4.ts"]
    ]
    result = filter_data(data, ["TCP_HIT", "http"])
    assert result == [
      [
        tcp_hit: "TCP_HIT/200",
        http: "http://foo.bar/BARF/a/b/c/123456/somefile.mp4.ts"
      ],
      [
        tcp_hit: "TCP_HIT/206",
        http: "http://foo.bar/BARF/e/f/789012/someotherfile.mp4.ts"
      ]
    ]
  end
  ...
end

list-vs-maps.ex

defmodule AccessLogApp.CLI do
  ...

  def filter_data(rows, strings) do
    Enum.map(rows, fn x ->
      for string <- strings do
        {
          String.to_atom(String.downcase(string)),
          Enum.at(Enum.filter(x, &String.contains?(&1, string)), 0)
        }
      end
    end)
  end

  ...
end

Option 2:

List of maps

test/access_log_app_test.exs

defmodule AccessLogAppTest do
  ...
  # filter_data
  test "filters data an array containing strings to match" do
    data = [
      ["a1", "TCP_HIT/200", "http://foo.bar/BARF/a/b/c/123456/somefile.mp4.ts"],
      ["a2", "TCP_HIT/206", "http://foo.bar/BARF/e/f/789012/someotherfile.mp4.ts"]
    ]
    result = filter_data(data, ["TCP_HIT", "http"])
    assert result == [
      %{
        tcp_hit: "TCP_HIT/200",
        http: "http://foo.bar/BARF/a/b/c/123456/somefile.mp4.ts"
      },
      %{
        tcp_hit: "TCP_HIT/206",
        http: "http://foo.bar/BARF/e/f/789012/someotherfile.mp4.ts"
      }
    ]
  end
  ...
end
lib/access_log_app/CLI.ex

defmodule AccessLogApp.CLI do
  ...

  def filter_data(rows, strings) do
    Enum.map(rows, fn x ->
      for string <- strings do
        {
          String.to_atom(String.downcase(string)),
          Enum.at(Enum.filter(x, &String.contains?(&1, string)), 0)
        }
      end
      |> Map.new
    end)
  end

  ...
end

That is it for today, but there is plenty more coming! Tomorrow's post will be part 4 of the nine post series on Processing a Log File with Elixir, where we will go through the lists of list of TCP_HIT/MISS and URLs and filtering to only contain ones with a specific URL path using Regex Match. If you like this post, please share and subscribe!

Launch Your Project

Get your project off the ground with Space-Rocket! Fill out the form below to get started.

Space-Rocket pin icon