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. :wave:

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

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. :stuck_out_tongue:

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