Je cherche essentiellement un équivalent Elixir de Ruby Array#sample
. Quelque chose qui me permettrait de faire ça:
list = [1,2,3,4,5,6,7]
sample(list)
#=> 4
sample(list, 3)
#=> [6, 2, 5]
Je n'ai rien trouvé non plus dans le Elixir List Docs .
Comme José Valim l'a dit dans sa réponse , dans Elixir 1.1
Et au-dessus, vous pouvez maintenant utiliser ces méthodes pour obtenir des éléments aléatoires à partir d'une liste:
Enum.random/1
- Pour obtenir un seul élément aléatoireEnum.take_random/2
- Pour obtenir plusieurs éléments aléatoiresExemple:
Enum.random(list) #=> 4
Enum.take_random(list, 3) #=> [3, 9, 1]
Enum.take_random(list, 1) #=> [7]
N'oubliez pas d'appeler :random.seed(:erlang.now)
d'abord !
Je ne suis toujours pas en mesure de trouver un moyen "approprié" et "magique" de le faire, mais c'est le mieux que j'ai pu trouver:
Pour obtenir un seul élément aléatoire:
list |> Enum.shuffle |> hd
#=> 4
Remarque: Cela donne une exception si le list
est vide
Pour obtenir plusieurs éléments aléatoires:
list |> Enum.shuffle |> Enum.take(3)
#=> [7, 1, 5]
Il n'y a pas une telle fonction dans Elixir 1.0, vous devez donc l'implémenter vous-même comme mentionné par les autres solutions. Cependant, Enum.random/1
vient avec Elixir v1.1: https://hexdocs.pm/elixir/Enum.html#random/1
Une autre façon (pour échantillonner un seul élément) est:
list |> Enum.at(:random.uniform(length(list)) - 1)
Peut-être préférable à l'autre méthode si vous travaillez avec des listes suffisamment grandes pour que le mélange de la liste entière puisse avoir un impact sur les performances.
commentaire de Gazler sur l'utilisation de :random.seed(:erlang.now)
s'applique toujours.
Si vous utilisez une version plus récente d'Elixir, il y a Enum.take_random/2
fonction ajoutée dans Elixir v1.1.
De la version 1.1 d'Elixir documentation :
Prend des éléments aléatoires d'une collection.
Notez que cette fonction traversera toute la collection pour obtenir la sous-liste aléatoire de la collection. Si vous voulez le nombre aléatoire entre deux entiers, la meilleure option est d'utiliser le module: random.
Donc, répondre à la question, prendre plusieurs éléments de la liste ressemblerait à:
list = [1,2,3,4,5,6,7]
Enum.take_random(list, 3)
#=> [2, 4, 1]
Ou, pour un seul article:
list = [1,2,3,4,5,6,7]
Enum.take_random(list, 1)
#=> [1]