我有一个函数,它是一个名为Sandbox的结构列表。见下文:
defmodule Sandbox do
defstruct description: nil, chance: nil
def all, do: [
%Sandbox{
description: "Description 1",
chance: [1..40]
},
%Sandbox{
description: "Description 2",
chance: [41..60]
},
%Sandbox{
description: "Description 3",
chance: [61..100]
},
]
我想随机选择一个Sandbox,每个Sandbox都有一个特定的概率。我的计划是根据每个项目的期望概率为一个名为“机会”的属性分配一系列数字,如上所示。然后,我将从1到100随机生成一个数字,并将其与每个Sandboxes列表进行匹配,以找到获胜的Sandbox。该功能需要返回获胜的沙箱。
问题:
你能写出一个函数来执行匹配并返回正确的Sandbox吗?一段时间以来一直尝试各种组合,似乎无法弄明白。
有人能想到更简单的方法吗?我觉得我的问题过于复杂。
非常感谢帮助。
答案 0 :(得分:3)
首先,你不应该在列表中包装范围。只需写下chance: 1..40
,chance: 41..60
等。以下是如何生成随机整数然后选择正确的沙箱:
defmodule Sandbox do
defstruct description: nil, chance: nil
def all, do: [
%Sandbox{
description: "Description 1",
chance: 1..40
},
%Sandbox{
description: "Description 2",
chance: 41..60
},
%Sandbox{
description: "Description 3",
chance: 61..100
},
]
def random do
rand = :rand.uniform(100)
Enum.find(all(), fn %{chance: chance} -> rand in chance end)
end
end
有人能想到更简单的方法吗?我觉得我的问题过于复杂。
这种方法对我来说很好看。如果性能是一个问题,那么将列表存储在树状数据结构中应该更快,我们可以比迭代每个元素更快地跳到右chance
。
答案 1 :(得分:2)
您可能遇到问题,因为chance
是range
内的list
。
这应该做你想要的:
defmodule Sandbox do
defstruct description: nil, chance: nil
def all, do: [
%Sandbox{
description: "Description 1",
chance: 1..40
},
%Sandbox{
description: "Description 2",
chance: 41..60
},
%Sandbox{
description: "Description 3",
chance: 61..100
},
]
@doc "Select a sandbox given a random value between 1 and 100"
def find(r) do
all() |> Enum.find(fn s -> r in s.chance end)
end
@doc "Select a sandbox at random"
def random() do
:rand.uniform(100) |> find()
end
end