List in tuple in reduce in for comprehension

how would I do that?

codons = ["Methionine", "Phenylalanine", "Tryptophan"]

for codon <- codons, reduce: {[]} do
  acc -> elem(acc, 0) ++ [codon]
end |> IO.inspect
** (ArgumentError) argument error
    :erlang.element(1, ["Methionine"])
    teste.exs:71: anonymous fn/2 in :elixir_compiler_0.__FILE__/1
    (elixir) lib/enum.ex:1948: Enum."-reduce/3-lists^foldl/2-0-"/3
    teste.exs:70: (file)
codons = ["Methionine", "Phenylalanine", "Tryptophan"]

for codon <- codons, reduce: {[]} do
  {acc} -> {[condon | acc]}
end |> IO.inspect

# {["Tryptophan", "Phenylalanine", "Methionine"]}

Will do it. We’re pattern matching the single tuple in the anonymous function, then appending to the list. Seems odd though.

3 Likes

Generally, avoid having the longer list on the left side of the ++ operator, as it is copied: Erlang -- The Seven Myths of Erlang Performance

Its innocuous with this case, the list is short. If it were larger, a Enum.reverse/1 after building the list with 'cons’ing (the [ value | whole_list ]) is more efficient.

1 Like

codons = [“Methionine”, “Phenylalanine”, “Tryptophan”]

for codon ← codons, reduce: {[]} do
{acc} → {acc ++ [condon]}
end |> IO.inspect

I would have to pipe in a anonymous function to reverse?

Is this some over-simplified example? I personally love comprehensions, but I wouldn’t use one given the input and desired result. The simplest solution is:

{Enum.reverse(codons)}

Or perhaps I’m misreading and you do not want reversed output, in which case the solution is even simpler:

{codons}