Elixir: What does a multiple-generator list comprehension look like without the syntax sugar?

流过昼夜 提交于 2019-12-11 21:42:36

问题


I'm trying to understand list comprehensions in Elixir.

The example I'm looking at is producing the permutations of a string from this answer.

def shuffle([], _), do: [[]]
def shuffle(_,  0), do: [[]]
def shuffle(list, i) do
  for x <- list, y <- shuffle(list, i-1), do: [x|y]
end

How does this double-generator comprehension look when re-written without the comprehension? I made an attempt to implement the algorithm myself, but my implementation is appending to the list, rather than prepending as in the comprehension. I want to write the algorithm without the comprehension but with identical behaviour.


回答1:


A comprehension without filters can be converted into a sequence of Enum.flat_map and Enum.map. Specifically, all but the last one will become flat_map and the last one will become map. Here's a translation of your code:

list
|> Enum.flat_map(fn x ->
  shuffle(list, i - 1)
  |> Enum.map(fn y ->
    [x | y]
  end)
end)

I tested with A.shuffle([1, 2, 3, 4, 5], 2) and the output looks identical to the original code in that question.




回答2:


Running Dogbert's example with the flat_map replaced with map really helped me see what was going on:

iex(1)> Permute.shuffle(~w(A B C), 3)
[
  [
    ["A", ["A", ["A"]], ["A", ["B"]], ["A", ["C"]]],
    ["A", ["B", ["A"]], ["B", ["B"]], ["B", ["C"]]],
    ["A", ["C", ["A"]], ["C", ["B"]], ["C", ["C"]]]
  ],
  [
    ["B", ["A", ["A"]], ["A", ["B"]], ["A", ["C"]]],
    ["B", ["B", ["A"]], ["B", ["B"]], ["B", ["C"]]],
    ["B", ["C", ["A"]], ["C", ["B"]], ["C", ["C"]]]
  ],
  [
    ["C", ["A", ["A"]], ["A", ["B"]], ["A", ["C"]]],
    ["C", ["B", ["A"]], ["B", ["B"]], ["B", ["C"]]],
    ["C", ["C", ["A"]], ["C", ["B"]], ["C", ["C"]]]
  ]
]


来源:https://stackoverflow.com/questions/50653654/elixir-what-does-a-multiple-generator-list-comprehension-look-like-without-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!