I want to know how do this in functional way.
input list
[%{
"id" => 1,
"value" => "x"
},
%{
"id" => 1
"value" => "y"
},
%{
"id" => 2
"value" => "z"
}]
resulted list
[%{
"id" => 1,
"values" => ["x","y"]
},
%{
"id" => 2,
"values" => ["z"]
}
]
I want to know how do this in functional way.
input list
[%{
"id" => 1,
"value" => "x"
},
%{
"id" => 1
"value" => "y"
},
%{
"id" => 2
"value" => "z"
}]
resulted list
[%{
"id" => 1,
"values" => ["x","y"]
},
%{
"id" => 2,
"values" => ["z"]
}
]
Try this code:
defmodule Example do
def sample(data), do: Enum.reduce(data, [], &sample/2)
defp sample(%{"id" => id, "value" => value}, [%{"id" => id, "values" => values} | tail]) do
[%{"id" => id, "values" => values ++ [value]} | tail]
end
defp sample(map, [head | tail]), do: [head | sample(map, tail)]
defp sample(%{"id" => id, "value" => value}, []), do: [%{"id" => id, "values" => [value]}]
end
and this test file:
defmodule ExampleTest do
use ExUnit.Case
test "Example.sample/1" do
input = [
%{"id" => 1, "value" => "x"},
%{"id" => 1, "value" => "y"},
%{"id" => 2, "value" => "z"}
]
expected = [
%{"id" => 1, "values" => ["x", "y"]},
%{"id" => 2, "values" => ["z"]}
]
assert Example.sample(input) === expected
end
end
btw. It would be nice if next time you would give valid Elixir
example data (as you have missed few ,
characters) and format them using builtin Elixir
formatter (mix format
task).
Enum module is your friend
iex> list = [%{"id" => 1, "value" => "x"}, %{"id" => 1, "value" => "y"}, %{"id" => 2, "value" => "z"}]
iex> Enum.group_by(list, fn x -> x["id"] end)
|> Enum.map(fn {k, v} -> %{k => Enum.map(v, & &1["value"])} end)
[%{1 => ["x", "y"]}, %{2 => ["z"]}]
I love a recursive solution for its didactic value, but in production code I’m more likely to rely upon the standard library and would do it something like this:
input
|> Enum.group_by(&(&1["id"]))
|> Enum.map(fn {id, list} -> %{"id" => id, "value" => Enum.map(list, &(&1["value"]))} end)
edit: Haha @kokolegorille you got in a minute ahead of me with the same basic approach
We share the same idea