Kyl*_*cot 5 functional-programming elixir
我有一个我想要使用的字符串列表构造一个新的n长度字符串.我如何从列表中随机选择一个元素,并将它们附加到字符串中,直到达到所需的长度?
parts = ["hello", "world", "foo bar", "baz"]
n = 25
# Example: "foo bar hello world baz baz"
Run Code Online (Sandbox Code Playgroud)
您需要使用Stream模块生成无限序列.一种方法可以是:
Stream.repeatedly(fn -> Enum.random(["hello", "world", "foo bar", "baz"]) end)
|> Enum.take(25)
Run Code Online (Sandbox Code Playgroud)
这是elixir 1.1到期Enum.random/1.看一下Stream模块文档.
更新1:
以同样的方式采取chars:
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
Run Code Online (Sandbox Code Playgroud)
这之后的一个字符串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
Run Code Online (Sandbox Code Playgroud)
并称之为:
iex > TakeN.take(["hello", "world", "foo bar", "baz"], 25)
"foo bar baz baz hello hello"
Run Code Online (Sandbox Code Playgroud)