Elixir 如何获得列表的排列?

Elixir 如何获得列表的排列?,elixir,Elixir,如何获得Elixir中列表的排列 例如,对于[“a”、“b”、“c”],我希望: # [["a", "b", "c"], ["a", "c", "b"], # ["b", "a", "c"], ["b", "c", "a"], # ["c", "a", "b"], ["c", "b", "a"]] 像这样: defmodule Permutations do def of([]) do [[]] end def of(list) do for h <- l

如何获得Elixir中列表的排列

例如,对于
[“a”、“b”、“c”]
,我希望:

# [["a", "b", "c"], ["a", "c", "b"], 
# ["b", "a", "c"], ["b", "c", "a"],
# ["c", "a", "b"], ["c", "b", "a"]]
像这样:

defmodule Permutations do
  def of([]) do
    [[]]
  end

  def of(list) do
    for h <- list, t <- of(list -- [h]), do: [h | t]
  end
end
defmodule置换
([])do的def
[[]]
结束
(列表)do的定义

对于h有一种稍微不同的方法,它还支持为结果列表指定所需的长度:

defmodule Permutations do
  def shuffle(list), do: shuffle(list, length(list))

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

这里有一个没有理解的版本:

defmodule Permute do
  def permute(_chars, building, 0) do
    [building]
  end

  def permute(chars, building, dec) do
    Stream.map(chars, fn char -> building ++ [char] end)
    |> Enum.flat_map(fn building -> permute(chars, building, dec - 1) end)
  end
end
有一个辅助函数允许输入为字符串也很有用:

def permute(str) do
  permute(String.split(str, "", trim: true), [], String.length(str))
end

为了便于发现,我把这段代码放在这里

defp-do模块
反宏置换(l,n)do
条款=
fn i->{:{:“i{i},[],长生不老药}结束)
枚举减少(1..n,返回,fn i,acc->
{:对于,[],[第(i)款,[do:acc]]}
(完)
结束
结束
灵巧的
需要P
定义置换3(列表),do:P.置换(列表,3)
结束
它使用普通AST返回嵌套的列表理解

T.permute3~w | a b |
#⇒ [
#[“a”、“a”、“a”]、[“b”、“a”、“a”],
#[“a”、“b”、“a”]、[“b”、“b”、“a”]],
#[“a”、“a”、“b”]、[“b”、“a”、“b”],
#[“a”、“b”、“b”]、[“b”、“b”、“b”]]
#  ]
由于早期的
范围
扩展,需要更多的努力才能将
n
作为一个参数传递出去,但这仍然是可行的。

I(重新)写这篇文章是为了更好地理解上面的答案:

def permutations(list) do
    if list == [] do
      [[]]
    else
      # recursively call itself on every element picked on the list and the remaining ones
      for h <- list, t <- permutations(list -- [h]) do
        [h | t]
      end
    end
  end

@OnorioCatenacci这不是一个很有信息量的评论:D我还不是一个长生不老药专家。如果你有时间发布一个,我很高兴看到一个更为惯用的解决方案——主要是我把它放在这里,因为我认为这是一个常见的问题,但我没有找到答案。下次我搜索时,我会的。我认为这是一个“自我提醒”其他人也可以使用。该评论并非真正针对你。它更多的是针对那些可能看到你的代码的人,他们不知道如何更好地假设这是编写Elixir代码的正确方法。那么@OnorioCatenacci为什么它不是惯用语呢?我也是Elixir的新手,希望能解释一下它与“rig”之间的区别谢谢。我没有时间提供一个更惯用的版本,所以这里是我的问题。1.([])的定义……将更惯用地写为([])的定义([]),do:[[]]
和2。)列表的尾部通常是模式匹配的,而不是通过
列表--[h]完成
您可能还会将列表分解为参数中的头/尾,如:
def of([h | t]=list)do
我认为这里的问题是将h/t视为参数中列表的头/尾,而它们是用于理解的临时变量使用x,y代替h/t,可能更清晰。PS:链接rosetta而不是块代码此处fwiw,我已经实现了所有返回
流的
s:我不确定这是否是所需的输出,有重复
def permutations(list) do
    if list == [] do
      [[]]
    else
      # recursively call itself on every element picked on the list and the remaining ones
      for h <- list, t <- permutations(list -- [h]) do
        [h | t]
      end
    end
  end
for a <-1..3, b <- 1..a*2 do
  "#{a} - #{b}"
end```