# Iterating over a lists of list of tuple

Here nums is a list of [list of {tuples}].

``````nums = [[{5,2}], [{10,2},{4,5}], [{6,5},{3,10},{2,15}]]
``````

I want to print output like this:

``````10 5 2
20 10 2 4 5
30 6 5 3 10 2 15
``````

Here, the first number is desired to be the product the tuple, followed by the tuples (factors).
The code I used,

``````Enum.each(nums, fn n ->
case n do
[{x,y}] ->IO.puts "#{x*y} #{x} #{y}"
end
end)
``````

But my code only handles the case where “nums” at any index has only 1 tuple.
What if it has n tuples and how can I handle the same?

So like this?

``````Enum.each(nums, fn n ->
case n do
[{x,y} | _] = list ->IO.puts("#{x*y} #{Enum.map(list, fn {a, b} -> "#{a} #{b} " end)}")
end
end)
``````

In IEx:

``````iex(1)> nums = [[{5,2}], [{10,2},{4,5}], [{6,5},{3,10},{2,15}]]
[[{5, 2}], [{10, 2}, {4, 5}], [{6, 5}, {3, 10}, {2, 15}]]
iex(2)> Enum.each(nums, fn n ->
...(2)>   case n do
...(2)>     [{x,y} | _] = list ->IO.puts("#{x*y} #{Enum.map(list, fn {a, b} -> "#{a} #{b} " end)}")
...(2)>   end
...(2)> end)
10 5 2
20 10 2 4 5
30 6 5 3 10 2 15
:ok
``````
1 Like

Just for fun, if the list was ‘flat’ like:

``````nums = [{5,2}, {10,2}, {4,5}, {6,5}, {3,10}, {2,15}]
``````

You could group them by their products really easily:

``````iex(4)> Enum.group_by(nums, fn {a, b} -> a * b end)
%{10 => [{5, 2}], 20 => [{10, 2}, {4, 5}], 30 => [{6, 5}, {3, 10}, {2, 15}]}
``````

Which you could then also loop over and print, the first value is the product, the second is the list of tuples. ^.^

1 Like

Welcome to the forum, @sagnik2911.

“Just for fun” might be selling it a bit short.

The flatten-group-print approach seems more robust to me, because we avoid the assumption that the given input is already grouped.

I also like this approach because we perform our data transformations first and then worry about printing, whereas the original approach kinda mixes it all together and hurts my feeble brain.

1 Like

Indeed, lol:

``````iex(1)> [{5,2}, {10,2}, {4,5}, {6,5}, {3,10}, {2,15}] |>
...(1)> Enum.group_by(fn {a, b} -> a * b end) |>
...(1)> Enum.each(fn {prod, values} ->
...(1)>   IO.puts(["#{prod} " | Enum.map(values, fn {a, b} -> "#{a} #{b} " end)])
...(1)> end)
10 5 2
20 10 2 4 5
30 6 5 3 10 2 15
:ok
``````
1 Like

Oh, oops; I could have been clearer. :101:

Regarding the assumption of pre-grouped tuples, I was talking about continuing to accept the original list-of-lists, perhaps due to a limitation of the source, e.g.:

``````[[{5,2}], [{10,2}, {4,5}], [{6,5}, {3,10}, {2,15}]]
|> List.flatten()
|> Enum.group_by(fn {a, b} -> a * b end)
|> ...
``````

But I agree that a single list of tuples would be a preferable input format, if the source can provide it.

2 Likes

Thanks @OvermindDL1 and @Ted for your help.
The filtering at the source using List.flatten looks much better. Applied that. And there goes my first project in Elixir. Thank you for your help. Elixir!

2 Likes

@OvermindDL1 and @Ted
Thank you guys for this . Saved me big time… You guys are rockstars… !!

2 Likes