Reputation: 131
I need to generate sets of series data with some already-determined values to test against an algorithm. The data sample data looks like ["apple", "orange", "apple", nil, "pineapple", nil]
and I need to every combination of apple, orange, and pineapple for each nil spot, for example in this case I need a list of lists that is
[
["apple", "orange", "apple", "apple", "pineapple", "apple"],
["apple", "orange", "apple", "orange", "pineapple", "apple"],
["apple", "orange", "apple", "pineapple", "pineapple", "apple"],
["apple", "orange", "apple", "apple", "pineapple", "orange"],
["apple", "orange", "apple", "orange", "pineapple", "orange"],
...
]
I am currently trying a recursive approach using List Comprehensions, but our company just started using Elixir, and I'm not yet familiar with how it all comes together.
I have this method called generate_sample_data
that takes a list of data and an accumulator (list of lists).
def generate_sample_data(list, valid_lists \\ []) do
case Enum.find_index(list, fn(f) -> f == nil end) do
nil -> [list | valid_lists]
index ->
for x <- ["apple", "orange", "pineapple"] do
list
|> List.update_at(index, fn(_)-> x end)
|> Enum.each(&generate_sample_data/2)
end
end
end
But I get the error #Function<4.433245229/2 in SampleData.generate_sample_data/2> with arity 2 called with 1 argument ("apple")
I don't know how to correctly turn these combinations from the list comprehension into a list of lists. Whatever I try seems to throw a different error at me, but I feel like I'm somewhat close.
Upvotes: 0
Views: 345
Reputation: 121010
In your particular case, the issue is here:
|> Enum.each(&generate_sample_data/2)
This is an attempt to call generate_sample_data/2
passing the only argument (the list that comes from the pipe.)
Also, Enum.each/2
does not make any sense there, because you are basically iterating over the elements of the valid list created on the previous step.
Another potential issue would be in the clause nil -> [list | acc]
you use never defined acc
local variable.
FWIW, here is the macro that produces all the permutations of the initial list:
defmacro permutations(l, n) do
clause = fn i -> {:<-, [], [{:"i#{i}", [], Elixir}, l]} end
return = Enum.map (1..n, fn i -> {:"i#{i}", [], Elixir} end)
Enum.reduce(1..n, return, fn i, acc ->
{:for, [], [clause.(i), [do: acc]]}
end)
end
Upvotes: 1