Skip to content

Commit

Permalink
Add -shuffle
Browse files Browse the repository at this point in the history
* dash.el (-shuffle): New function.
* dev/examples.el (-shuffle): New example.

* README.md:
* dash.texi:
Regenerate docs.
  • Loading branch information
cireu committed Mar 17, 2023
1 parent 516659f commit 27c5eac
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
24 changes: 24 additions & 0 deletions README.md
Expand Up @@ -295,6 +295,7 @@ Other list functions not fit to be classified elsewhere.
* [`-butlast`](#-butlast-list) `(list)`
* [`-sort`](#-sort-comparator-list) `(comparator list)`
* [`-to-head`](#-to-head-n-list) `(n list)`
* [`-shuffle`](#-shuffle-list) `(list)`
* [`-list`](#-list-arg) `(arg)`
* [`-fix`](#-fix-fn-list) `(fn list)`

Expand Down Expand Up @@ -2318,6 +2319,29 @@ if the first element should sort before the second.
(--sort (< it other) '(3 1 2)) ;; => (1 2 3)
```

#### -to-head `(n list)`

Return a new list that move the element at `n`th to the head of old `list`.

```el
(-to-head 3 '(1 2 3 4 5)) ;; => (4 1 2 3 5)
(-to-head 5 '(1 2 3 4 5)) ;; peculiar error
(let ((l '(1 2 3 4 5))) (list (-to-head 2 l) l)) ;; => ((3 1 2 4 5) (1 2 3 4 5))
```

#### -shuffle `(list)`

Return a new shuffled `list`.

The returned list is shuffled by using Fisher-Yates' Algorithm. See
https://en.wikipedia.org/wiki/Fisher-Yates_shuffle for more details.

```el
(progn (random "dash1") (-shuffle '(1 2 3 4 5 6 7))) ;; => (2 7 6 4 5 1 3)
(progn (random "dash2") (-shuffle '(1 2 3 4 5 6 7))) ;; => (1 5 2 4 3 7 6)
(let ((l '(1 2 3 4 5 6 7))) (random "dash3") (list (-shuffle '(1 2 3 4 5 6 7)) l)) ;; => ((3 4 1 5 7 6 2) (1 2 3 4 5 6 7))
```

#### -list `(arg)`

Ensure `arg` is a list.
Expand Down
14 changes: 14 additions & 0 deletions dash.el
Expand Up @@ -3248,6 +3248,20 @@ if the first element should sort before the second."
(target (pop rest)))
(cons target (nconc head rest))))

(defun -shuffle (list)
"Return a new shuffled LIST.
The returned list is shuffled by using Fisher-Yates' Algorithm. See
https://en.wikipedia.org/wiki/Fisher-Yates_shuffle for more details."
(declare (pure t) (side-effect-free t))
(let* ((len (length list))
(random-nums (-map #'random (number-sequence len 1 -1)))
result)
(--each random-nums
(setq list (-to-head it list))
(push (pop list) result))
(nreverse result)))

(defun -list (&optional arg &rest args)
"Ensure ARG is a list.
If ARG is already a list, return it as is (not a copy).
Expand Down
23 changes: 23 additions & 0 deletions dash.texi
Expand Up @@ -3498,6 +3498,29 @@ Return a new list that move the element at Nth to the head of old @var{list}.
@end example
@end defun

@anchor{-shuffle}
@defun -shuffle (list)
Return a new shuffled @var{list}.

The returned list is shuffled by using Fisher-Yates' Algorithm. See
https://en.wikipedia.org/wiki/Fisher-Yates_shuffle for more details.

@example
@group
(progn (random "dash1") (-shuffle '(1 2 3 4 5 6 7)))
@result{} (2 7 6 4 5 1 3)
@end group
@group
(progn (random "dash2") (-shuffle '(1 2 3 4 5 6 7)))
@result{} (1 5 2 4 3 7 6)
@end group
@group
(let ((l '(1 2 3 4 5 6 7))) (random "dash3") (list (-shuffle '(1 2 3 4 5 6 7)) l))
@result{} ((3 4 1 5 7 6 2) (1 2 3 4 5 6 7))
@end group
@end example
@end defun

@anchor{-list}
@defun -list (arg)
Ensure @var{arg} is a list.
Expand Down
12 changes: 12 additions & 0 deletions dev/examples.el
Expand Up @@ -1927,6 +1927,18 @@ related predicates."
(let ((l '(1 2 3 4 5)))
(list (-to-head 2 l) l)) => '((3 1 2 4 5) (1 2 3 4 5)))

(defexamples -shuffle
(progn
(random "dash1")
(-shuffle '(1 2 3 4 5 6 7))) => '(2 7 6 4 5 1 3)
(progn
(random "dash2")
(-shuffle '(1 2 3 4 5 6 7))) => '(1 5 2 4 3 7 6)
(let ((l '(1 2 3 4 5 6 7)))
(random "dash3")
(list (-shuffle '(1 2 3 4 5 6 7)) l)) => '((3 4 1 5 7 6 2) (1 2 3 4 5 6 7))
(-shuffle nil) => nil)

(defexamples -list
(-list 1) => '(1)
(-list '()) => '()
Expand Down

0 comments on commit 27c5eac

Please sign in to comment.