#Loop with accumulator in Elixir
49 messages · Page 1 of 1 (latest)
you'll need to use Enum.reduce to accumulate both the sum and the results list
(or the reduce option of for)
I'm not sure how syntax would look like for both sum and res
I'm a newbie
I know how to do Enum.reduce over one variable
You can use a tuple that contains both variables
In this case Enum.map_reduce/3 is what you want - https://hexdocs.pm/elixir/1.12/Enum.html#map_reduce/3
Thanks guys, I should have looked at documentation more carefully
Didn't know i can return tuple {result, accumulator }
Btw. is there a way to do the same thing with comprehensions?
Yes, there's a reduce option
Comprehensions are insanely powerful in elixir. Much more so than in, say, python
The example in documentation is not showing how to set initial value for the accumulator
Yes it is, it's an empty map
so I should do acc -> {result, accumulator } ?
You need to give the tuple to reduce:
acc is the accumulator, so you'll need to pattern match out the tuple there and return a tuple from the body of the comprehension
So, {result, sum} -> something
Where something applies the computation and returns a new tuple
Like this?
initial = 10
for idx <- 1..10, reduce: {initial, []} do
{res, acc} -> some_fun(acc)
end
def some_fun(acc) do
{%{hello: "world"}, acc+1}
end
Well, acc in that instance is a list and you can't add to it with +
No, it's not. It's an empty list initially
Idx is a number
You don't seem to be doing anything with it
Correction
initial = 10
for idx <- 1..10, reduce: {[], initial} do
{res, acc} -> some_fun(acc, idx)
end
def some_fun(acc, idx) do
{%{hello: "world"}, acc+idx}
end
well it doesn't 😄
It will not
Do you want to append a bunch of maps to the list?if you want to do that, you'll need to wither pass the list to the function and append in there, or take the return value of the function, pattern match out the parts and append the map to the list in the body of the for
yes
If you want to make it simple:
Enum.map_reduce(1..10, 0, &some_fun(&2, &1))
And it will do what you want
They were interested in comprehensions
They wanted to achieve what is in the question, it was latter sugested to use comprehesions, but first proposal was to use Enum.reduce/3 which was rejected only becasue @mild inlet didn't know how to do reduce over multiple values
Ahhh, I missed it
And it can, but it's not as concise
Indeed
Alright, I did it with Enum.map_reduce. Thanks for the help guys
I'm at a keyboard... Here's how you'd do it in a comp:
initial = 10
for idx <- 1..10, reduce: {[], initial} do
{res, acc} -> {[%{hello: "world"} | res], acc + idx}
end
You will need to reverse the result list afterwards
not in this example, since they're all the same 😉