我有一个函数,它是一个名为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。该功能需要返回获胜的沙盒。
问题:
真的很感激帮助。
首先,您不应该将范围包装在列表中。只需编写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
。
你可能遇到问题,因为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