我有一个我想要使用的字符串列表构造一个n
长度的新字符串。我如何从列表中随机选择一个元素,并将它们附加到字符串中,直到我达到所需的长度?
parts = ["hello", "world", "foo bar", "baz"]
n = 25
# Example: "foo bar hello world baz baz"
答案 0 :(得分:7)
您需要使用Stream
模块生成无限序列。一种方法可以是:
Stream.repeatedly(fn -> Enum.random(["hello", "world", "foo bar", "baz"]) end)
|> Enum.take(25)
这是elixir 1.1 due 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
之后,这一条曲线变焦。
答案 1 :(得分:5)
这是我的用法,它使用尾递归:
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"