Reputation: 3147
I have a list of addresses and I need to fix the records, some of the records have the house number as a range and I need to split it into multiple records. How would I enumerate over the list and fix/duplicate the records?
defmodule EnumTesting do
def list_stuff() do
list = [ %{street: "street", nr: "2" }, %{street: "street", nr: "4" }, %{street: "street", nr: "6-10" } ]
list |> Enum.filter(&needs_fixing?(&1))
end
defp needs_fixing?(item) do
String.contains?(item.nr, "-")
end
end
Expected result:
[ %{street: "street", nr: "2" }, %{street: "street", nr: "4" }, %{street: "street", nr: "6" }, %{street: "street", nr: "8" }, %{street: "street", nr: "10" } ]
Upvotes: 0
Views: 318
Reputation: 121000
def fix!(%{street: street, nr: nr}) do
case Regex.scan(~r|\d+|, nr, capture: :all_but_first) do
[nr] -> [%{street: street, nr: nr}]
[from, two] -> String.to_integer(from)..String.to_integer(to)
|> Enum.map(fn i -> %{street: street, nr: "#{i}"} end)
_ -> raise "Something went wrong: input is incorrect!"
end
end
def list_stuff() do
list = [%{street: "street", nr: "2" },
%{street: "street", nr: "4" },
%{street: "street", nr: "6-10" } ]
list |> Enum.flat_map(&fix!/1)
end
The above will return 5 records for the last element, 6
through 10
, but as you have stated in comments, you are aware on how to deal with that.
Upvotes: 0
Reputation: 5812
You have need_fixing?
fine, so all you need to do is implement fixing function.
def fixing_function(%{nr: range, street: street}) do
[a, b] = range |> String.split("-") |> Enum.map(&String.to_integer/1)
for value <- Range.new(a, b), do: %{street: street, nr: "#{value}"}
end
This gives you fixed addresses and you add append this list to the list of valid entries.
It returns entries for 6, 7, 8, 9 and 10. To use it only for even or odd number you can apply there simple filter function, use :lists:seq
or Stream.iterate
.
Upvotes: 1