如何在 Elm 的给定列表中获取随机元素?
How to get a random element in a given List in Elm?
我正在制作一款滑动益智游戏:
从这个初始位置开始,我想洗牌,比如说 100 步。
我希望每次都以不同的方式洗牌。
这可能意味着我需要每次用不同的号码呼叫Random.initialSeed
,这意味着我需要使用类似当前时间的东西。
很遗憾,我找不到如何获取当前时间。
在每个给定的状态下,我都有一个可能的动作列表。比如上面的初始位置:[MoveRight, MoveDown]
所以,基本上,我的问题是:如何在给定列表中获取随机元素?
share-elm 示例将不胜感激。
粗略的答案(现在不在编译器附近):
如果您想根据当前时间改变种子,请将 Time.every
添加到您的信号图中:
http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Time#every
在你的模型中保留最后一次看到的时间戳,然后,当你需要洗牌时,用它来为你的随机数播种。生成一个[1,长度列表]范围内的整数,然后选择该索引的元素。
希望这是一个足够的提示,如果不够请大声说出来,我会在有机会时详细说明。
这是对 pdamoc 答案的修订。它更紧密地遵循 The Elm Architecture,但更重要的是,它保存了从印刷机到印刷机的随机种子。如果您继续使用初始种子,您将不会获得随机性。我在另一个版本中只得到偶数或奇数(得到偶数,刷新,得到赔率)。在您的程序中只调用一次 Random.initialSeed
很重要,通常是在初始模型的定义中。
还有a library(我写的)处理数组的随机操作。
import Html exposing (..)
import Html.Events exposing (onClick)
import Random exposing (initialSeed, int, generate, Seed)
type alias Model =
{ list : List Int , currentElement : Maybe Int, seed : Seed}
init : Model
init = {list = [1..10], currentElement = Nothing, seed = initialSeed 42 }
type Action = NoOp | Click
actions : Signal.Mailbox Action
actions = Signal.mailbox NoOp
update : Action -> Model -> Model
update action model =
case action of
NoOp -> model
Click ->
let gen = Random.int 0 (List.length model.list - 1)
-- since we know the list is constant we don't have to
-- redefine the generator every time, but we will anyway
(i, seed) = Random.generate gen model.seed
elem = List.drop i model.list |> List.head
in {model| currentElement <- elem, seed <- seed}
model : Signal Model
model = Signal.foldp update init actions.signal
view : Signal.Address Action -> Model -> Html
view address model =
let
current = model.currentElement
|> Maybe.map toString
|> Maybe.withDefault "NONE"
in
div []
[ text <| toString model.list
, br [] []
, text <| "Current Element: " ++ current
, br [] []
, button [onClick address Click ] [text "Click for Random Element"]
]
main = Signal.map (view actions.address) model
我创建了 Elm 的 StartApp 示例的一个变体,其中包括每个事件的时间,仅当事件发生时。
https://gist.github.com/z5h/41ca436679591b6c3e51
您的更新函数现在看起来像:
update : action -> Time -> model -> (model, Effects action)
我正在制作一款滑动益智游戏:
从这个初始位置开始,我想洗牌,比如说 100 步。
我希望每次都以不同的方式洗牌。
这可能意味着我需要每次用不同的号码呼叫Random.initialSeed
,这意味着我需要使用类似当前时间的东西。
很遗憾,我找不到如何获取当前时间。
在每个给定的状态下,我都有一个可能的动作列表。比如上面的初始位置:[MoveRight, MoveDown]
所以,基本上,我的问题是:如何在给定列表中获取随机元素?
share-elm 示例将不胜感激。
粗略的答案(现在不在编译器附近):
如果您想根据当前时间改变种子,请将 Time.every
添加到您的信号图中:
http://package.elm-lang.org/packages/elm-lang/core/2.1.0/Time#every
在你的模型中保留最后一次看到的时间戳,然后,当你需要洗牌时,用它来为你的随机数播种。生成一个[1,长度列表]范围内的整数,然后选择该索引的元素。
希望这是一个足够的提示,如果不够请大声说出来,我会在有机会时详细说明。
这是对 pdamoc 答案的修订。它更紧密地遵循 The Elm Architecture,但更重要的是,它保存了从印刷机到印刷机的随机种子。如果您继续使用初始种子,您将不会获得随机性。我在另一个版本中只得到偶数或奇数(得到偶数,刷新,得到赔率)。在您的程序中只调用一次 Random.initialSeed
很重要,通常是在初始模型的定义中。
还有a library(我写的)处理数组的随机操作。
import Html exposing (..)
import Html.Events exposing (onClick)
import Random exposing (initialSeed, int, generate, Seed)
type alias Model =
{ list : List Int , currentElement : Maybe Int, seed : Seed}
init : Model
init = {list = [1..10], currentElement = Nothing, seed = initialSeed 42 }
type Action = NoOp | Click
actions : Signal.Mailbox Action
actions = Signal.mailbox NoOp
update : Action -> Model -> Model
update action model =
case action of
NoOp -> model
Click ->
let gen = Random.int 0 (List.length model.list - 1)
-- since we know the list is constant we don't have to
-- redefine the generator every time, but we will anyway
(i, seed) = Random.generate gen model.seed
elem = List.drop i model.list |> List.head
in {model| currentElement <- elem, seed <- seed}
model : Signal Model
model = Signal.foldp update init actions.signal
view : Signal.Address Action -> Model -> Html
view address model =
let
current = model.currentElement
|> Maybe.map toString
|> Maybe.withDefault "NONE"
in
div []
[ text <| toString model.list
, br [] []
, text <| "Current Element: " ++ current
, br [] []
, button [onClick address Click ] [text "Click for Random Element"]
]
main = Signal.map (view actions.address) model
我创建了 Elm 的 StartApp 示例的一个变体,其中包括每个事件的时间,仅当事件发生时。
https://gist.github.com/z5h/41ca436679591b6c3e51
您的更新函数现在看起来像:
update : action -> Time -> model -> (model, Effects action)