aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorinoas <mail@inoas.com>2022-10-27 20:47:12 +0000
committerGitHub <noreply@github.com>2022-10-27 21:47:12 +0100
commit6c9a956af844379aa8d33fa3832636b33493f776 (patch)
treebe8da108d9481945c28979e25cda1143180655e8 /src
parente6401929ce83b332e05cc86db58e5d537b0ea87f (diff)
downloadgleam_stdlib-6c9a956af844379aa8d33fa3832636b33493f776.tar.gz
gleam_stdlib-6c9a956af844379aa8d33fa3832636b33493f776.zip
add list.shuffle (#360)
Diffstat (limited to 'src')
-rw-r--r--src/gleam/list.gleam42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam
index 04d311e..268642d 100644
--- a/src/gleam/list.gleam
+++ b/src/gleam/list.gleam
@@ -23,6 +23,7 @@
////
import gleam/int
+import gleam/float
import gleam/order.{Order}
import gleam/pair
@@ -1822,3 +1823,44 @@ pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) {
}
}
}
+
+fn do_shuffle_pair_unwrap(list: List(#(Float, a)), acc: List(a)) -> List(a) {
+ case list {
+ [] -> acc
+ _ -> {
+ let [elem_pair, ..enumerable] = list
+ do_shuffle_pair_unwrap(enumerable, [elem_pair.1, ..acc])
+ }
+ }
+}
+
+fn do_shuffle_by_pair_indexes(
+ list_of_pairs: List(#(Float, a)),
+) -> List(#(Float, a)) {
+ sort(
+ list_of_pairs,
+ fn(a_pair: #(Float, a), b_pair: #(Float, a)) -> Order {
+ float.compare(a_pair.0, b_pair.0)
+ },
+ )
+}
+
+/// Takes a list, randomly sorts all items and returns the shuffled list.
+///
+/// ## Example
+///
+/// ```gleam
+/// list.range(1, 10)
+/// |> list.shuffle()
+/// > [1, 6, 9, 10, 3, 8, 4, 2, 7, 5]
+/// ```
+///
+/// Notice: This function uses Erlang's `:rand` module or Javascript's
+/// `Math.random()` to calcuate the index shuffling.
+///
+pub fn shuffle(list: List(a)) -> List(a) {
+ list
+ |> fold(from: [], with: fn(acc, a) { [#(float.random(0.0, 1.0), a), ..acc] })
+ |> do_shuffle_by_pair_indexes()
+ |> do_shuffle_pair_unwrap([])
+}