Skip to content

Instantly share code, notes, and snippets.

@cloud8421
Created August 10, 2016 14:38
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cloud8421/7293f2527e8086a1ca7b94d78131a623 to your computer and use it in GitHub Desktop.
Save cloud8421/7293f2527e8086a1ca7b94d78131a623 to your computer and use it in GitHub Desktop.
Maps and match specs in elixir
defmodule MsTest do
use ExUnit.Case
doctest Ms
@bob %{name: "Bob", job: "developer"}
@alice %{name: "Alice", job: "musician"}
@john %{name: "John", job: "musician"}
@ada %{name: "Ada", job: "developer"}
@alan %{name: "Alan", job: "developer"}
@table :users
setup_all do
t = :ets.new(@table, [:ordered_set, :named_table])
:ets.insert(t, {1, @bob})
:ets.insert(t, {2, @alice})
:ets.insert(t, {3, @ada})
:ets.insert(t, {4, @john})
:ets.insert(t, {5, @alan})
:ok
end
test "all users" do
q = [
{
{:_, :_},
[],
[{:element, 2, :"$_"}]
}
]
assert [@bob, @alice, @ada, @john, @alan] == :ets.select(@table, q)
end
test "users by name" do
q = [
{
{:_, %{name: "Bob"}},
[],
[{:element, 2, :"$_"}]
}
]
assert [@bob] == :ets.select(@table, q)
end
test "all developers" do
q = [
{
{:_, %{job: "developer"}},
[],
[{:element, 2, :"$_"}]
}
]
assert [@bob, @ada, @alan] == :ets.select(@table, q)
end
test "all developers - variant" do
q = [
{
{:"$1", %{job: :"$2"}},
[{:"==", :"$2", {:const, "developer"}}],
[{:element, 2, :"$_"}],
}
]
assert [@bob, @ada, @alan] == :ets.select(@table, q)
end
test "all non developers" do
q = [
{
{:"$1", %{job: :"$2"}},
[{:"/=", :"$2", {:const, "developer"}}],
[{:element, 2, :"$_"}],
}
]
assert [@alice, @john] == :ets.select(@table, q)
end
test "all developers, paginated" do
q = [
{
{:_, %{job: "developer"}},
[],
[{:element, 2, :"$_"}]
}
]
{first_page, cont} = :ets.select(@table, q, 2)
assert [@bob, @ada] == first_page
assert {[@alan], :"$end_of_table"} == :ets.select(cont)
end
end
@lessless
Copy link

thanks a lot @cloud8421! do you think it's possible to retrieve only part of the map, say :name with select?

@cloud8421
Copy link
Author

@lessless Almost 4 years late, sorry. This query filters by job ("developer") and returns only the names as a list.

q = [
  {
    {:"$1", %{job: :"$2", name: :"$3"}},
    [{:==, :"$2", {:const, "developer"}}],
    [:"$3"]
  }
]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment