emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master bd22beb: Add seq-random-elt to seq.el


From: Nicolas Petton
Subject: [Emacs-diffs] master bd22beb: Add seq-random-elt to seq.el
Date: Tue, 25 Oct 2016 10:33:09 +0000 (UTC)

branch: master
commit bd22beb6e4054c659e8c31931c421f60e9719c65
Author: Damien Cassou <address@hidden>
Commit: Nicolas Petton <address@hidden>

    Add seq-random-elt to seq.el
    
    * lisp/emacs-lisp/seq.el (seq-random-elt): Add function to return a
      random element from it's sequence parameter.
    
    * test/lisp/emacs-lisp/seq-tests.el (test-seq-random-elt-take-all
      test-seq-random-elt-return-nil): Test the new function
    
    * doc/lispref/sequences.texi: Document the new function
---
 doc/lispref/sequences.texi        |   20 ++++++++++++++++++++
 lisp/emacs-lisp/seq.el            |    9 ++++++++-
 test/lisp/emacs-lisp/seq-tests.el |   17 +++++++++++++++++
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 08e5e3a..b6874bf 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -1037,6 +1037,26 @@ followed by a variable name to be bound to the rest of
 @end example
 @end defmac
 
address@hidden seq-random-elt sequence
+  This function returns an element of @var{sequence} taken at random. If 
@var{sequence} is nil, the function returns nil.
+
address@hidden
address@hidden
+(seq-random-elt [1 2 3 4])
address@hidden 3
+(seq-random-elt [1 2 3 4])
address@hidden 2
+(seq-random-elt [1 2 3 4])
address@hidden 4
+(seq-random-elt [1 2 3 4])
address@hidden 2
+(seq-random-elt [1 2 3 4])
address@hidden 1
address@hidden group
address@hidden example
+
+  If @var{sequence} is empty, the function signals an error.
address@hidden defun
 
 @node Arrays
 @section Arrays
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 85702f4..5c89d2b 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <address@hidden>
 ;; Keywords: sequences
-;; Version: 2.18
+;; Version: 2.19
 ;; Package: seq
 
 ;; Maintainer: address@hidden
@@ -476,6 +476,13 @@ SEQUENCE must be a sequence of numbers or markers."
   "Return element of SEQUENCE at the index N.
 If no element is found, return nil."
   (ignore-errors (seq-elt sequence n)))
+
+(cl-defgeneric seq-random-elt (sequence)
+  "Return a random element from SEQUENCE.
+Return nil if SEQUENCE is nil."
+  (if (seq-empty-p sequence)
+      (error "Sequence cannot be empty")
+    (seq-elt sequence (random (seq-length sequence)))))
 
 
 ;;; Optimized implementations for lists
diff --git a/test/lisp/emacs-lisp/seq-tests.el 
b/test/lisp/emacs-lisp/seq-tests.el
index c2065c6..6d17b7c 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -28,6 +28,7 @@
 
 (require 'ert)
 (require 'seq)
+(require 'map)
 
 (defmacro with-test-sequences (spec &rest body)
   "Successively bind VAR to a list, vector, and string built from SEQ.
@@ -371,5 +372,21 @@ Evaluate BODY for each created sequence.
     (should (equal (seq-sort-by #'seq-length #'> seq)
                    ["xxx" "xx" "x"]))))
 
+(ert-deftest test-seq-random-elt-take-all ()
+  (let ((seq '(a b c d e))
+        (count '()))
+    (should (= 0 (map-length count)))
+    (dotimes (_ 1000)
+      (let ((random-elt (seq-random-elt seq)))
+        (map-put count
+                 random-elt
+                 (map-elt count random-elt 0))))
+    (should (= 5 (map-length count)))))
+
+(ert-deftest test-seq-random-elt-signal-on-empty ()
+  (should-error (seq-random-elt nil))
+  (should-error (seq-random-elt []))
+  (should-error (seq-random-elt "")))
+
 (provide 'seq-tests)
 ;;; seq-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]