使用 Elixir 从列表构造一个长度为 n 的随机字符串

Construct a random string of n length from a list using Elixir

我有一个字符串列表,我想用它来构造一个 n 长度的新字符串。我将如何从列表中随机选择一个元素,并将它们附加到字符串,直到达到所需的长度?

parts = ["hello", "world", "foo bar", "baz"]
n = 25
# Example: "foo bar hello world baz baz"

您需要使用Stream模块来生成无限序列。一种方法可以是:

Stream.repeatedly(fn -> Enum.random(["hello", "world", "foo bar", "baz"]) end)
|> Enum.take(25)

这是长生不老药 1.1 Enum.random/1。查看 Stream 模块文档。

更新 1:

使用相同的方法获取字符:

defmodule CustomEnum do
  def take_chars_from_list(list, chars) do
    Stream.repeatedly(fn -> Enum.random(list) end)
    |> Enum.reduce_while([], fn(next, acc) ->
      if String.length(Enum.join(acc, " ")) < chars do
        {:cont, [next | acc]} 
      else
        {:halt, Enum.join(acc, " ")}
      end
    end)
    |> String.split_at(chars)
    |> elem(0)
  end
end

n.

之后的这一条字符

这是我的做法,它使用了尾递归:

defmodule TakeN do
    def take(list, n) do
        if length(list) == 0 do
            :error
        else
            do_take(list, n, [])
        end
    end

    defp do_take(_, n, current_list) when n < 0 do
        Enum.join(current_list, " ")
    end

    defp do_take(list, n, current_list) do
        random = Enum.random(list)

        # deduct the length of the random element from the remaining length (+ 1 to account for the space)
        do_take(list, n - (String.length(random) + 1), [random|current_list])
    end
end

并调用它:

iex > TakeN.take(["hello", "world", "foo bar", "baz"], 25)
"foo bar baz baz hello hello"