使用 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"
我有一个字符串列表,我想用它来构造一个 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"