web-dev-qa-db-ja.com

リストからランダム要素を取得する

基本的には、RubyのElixirに相当するものを探しています Array#sample 。これを可能にする何か:

list = [1,2,3,4,5,6,7]

sample(list)
#=> 4

sample(list, 3)
#=> [6, 2, 5]

Elixir List Docs にも何も見つかりませんでした。

29
Sheharyar

更新された回答

JoséValimが his answer で、_Elixir 1.1_以上で言ったように、これらのメソッドを使用して、リストからランダムな要素を取得できます。

例:

_Enum.random(list)                         #=> 4

Enum.take_random(list, 3)                 #=> [3, 9, 1]
Enum.take_random(list, 1)                 #=> [7]
_

最初に:random.seed(:erlang.now)を呼び出すことを忘れないでください!


元の回答

私はまだこれを行うための「適切な」「魔法の」方法を見つけることができませんが、これは私が思いつく最高の方法です:

単一のランダム要素を取得する場合:

_list |> Enum.shuffle |> hd
#=> 4
_

注:listが空の場合、これにより例外が発生します

複数のランダム要素を取得する場合:

_list |> Enum.shuffle |> Enum.take(3)
#=> [7, 1, 5]
_
50
Sheharyar

Elixir 1.0にはそのような機能はないため、他のソリューションで言及されているように、自分で実装する必要があります。しかしながら、 Enum.random/1はElixir v1.1に付属しています: https://hexdocs.pm/elixir/Enum.html#random/1

10
José Valim

別の方法(1つの要素のみをサンプリングする場合)は次のとおりです。

_list |> Enum.at(:random.uniform(length(list)) - 1)
_

リスト全体をシャッフルするほど十分に大きいリストで作業している場合は、他の方法よりもパフォーマンスに影響する可能性があります。

ガズラーのコメント:random.seed(:erlang.now)の使用については引き続き適用されます。

5
Simon Woolf

Elixirの新しいバージョンを実行している場合は、Enum.take_random/2 Elixir v1.1で追加された関数。

Elixirのv1.1から ドキュメント

コレクションからランダムなアイテムを取得します。

この関数はコレクション全体を走査して、コレクションのランダムなサブリストを取得することに注意してください。 2つの整数の間の乱数が必要な場合、最適なオプションは:randomモジュールを使用することです。

したがって、質問に答えて、リストから複数の項目を取得すると、次のようになります。

list = [1,2,3,4,5,6,7]
Enum.take_random(list, 3)
#=> [2, 4, 1]

または、単一のアイテムの場合:

list = [1,2,3,4,5,6,7]
Enum.take_random(list, 1)
#=> [1]
1
Ilija Eftimov