From 41649089e35cfb5a9c4d3b518e92c7eaaa9d424d Mon Sep 17 00:00:00 2001 From: Johan Andersson Date: Mon, 12 Aug 2013 21:33:46 +0200 Subject: [PATCH] Add -min, -max, -min-by and -max-by. --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ dash.el | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ dev/examples.el | 22 ++++++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/README.md b/README.md index 51209ae..98354b8 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,10 @@ Or you can just dump `dash.el` in your load path somewhere. * [-count](#-count-pred-list) `(pred list)` * [-sum](#-sum-list) `(list)` * [-product](#-product-list) `(list)` +* [-min](#-min-x-rest-xs) `(x &rest xs)` +* [-min-by](#-min-by-pred-list) `(pred list)` +* [-max](#-max-x-rest-xs) `(x &rest xs)` +* [-max-by](#-max-by-pred-list) `(pred list)` * [-any?](#-any-pred-list) `(pred list)` * [-all?](#-all-pred-list) `(pred list)` * [-none?](#-none-pred-list) `(pred list)` @@ -315,6 +319,46 @@ Return the product of `list`. (-product '(1 2 3)) ;; => 6 ``` +### -min `(x &rest xs)` + +Return the smallest value of all arguments. + +```cl +(-min 0) ;; => 0 +(-min 1) ;; => 1 +(-min 1 2 3) ;; => 1 +``` + +### -min-by `(pred list)` + +Call `pred` for each item in `list` and return item with smallest value. + +```cl +(-min-by 'identity '()) ;; => nil +(-min-by 'identity '(1)) ;; => 1 +(--min-by (cdr it) '((a . 1) (b . 2) (c . 3))) ;; => '(a . 1) +``` + +### -max `(x &rest xs)` + +Return the largest value of all arguments. + +```cl +(-max 0) ;; => 0 +(-max 1) ;; => 1 +(-max 1 2 3) ;; => 3 +``` + +### -max-by `(pred list)` + +Call `pred` for each item in `list` and return item with largest value. + +```cl +(-max-by 'identity '()) ;; => nil +(-max-by 'identity '(1)) ;; => 1 +(--max-by (cdr it) '((a . 1) (b . 2) (c . 3))) ;; => '(c . 3) +``` + ### -any? `(pred list)` Returns t if (`pred` x) is non-nil for any x in `list`, else nil. diff --git a/dash.el b/dash.el index 31e9a83..ba5ec25 100644 --- a/dash.el +++ b/dash.el @@ -893,6 +893,48 @@ Returns nil if N is less than 1." "Return the product of LIST." (apply '* list)) +(defun -min (x &rest xs) + "Return the smallest value of all arguments." + (apply 'min (cons x xs))) + +(defun -min-by (pred list) + "Call PRED for each item in LIST and return item with smallest value." + (let (min-item (min-value most-positive-fixnum)) + (-each + list + (lambda (item) + (let ((item-value (funcall pred item))) + (when (< item-value min-value) + (setq min-value item-value) + (setq min-item item))))) + min-item)) + +(defmacro --min-by (form list) + "Anaphoric form of `-min-by'." + (declare (debug t)) + `(-min-by (lambda (it) ,form) ,list)) + +(defun -max (x &rest xs) + "Return the largest value of all arguments." + (apply 'max (cons x xs))) + +(defun -max-by (pred list) + "Call PRED for each item in LIST and return item with largest value." + (let (max-item (max-value most-negative-fixnum)) + (-each + list + (lambda (item) + (let ((item-value (funcall pred item))) + (when (> item-value max-value) + (setq max-value item-value) + (setq max-item item))))) + max-item)) + +(defmacro --max-by (form list) + "Anaphoric form of `-max-by'." + (declare (debug t)) + `(-max-by (lambda (it) ,form) ,list)) + (eval-after-load "lisp-mode" '(progn (let ((new-keywords '( @@ -998,6 +1040,12 @@ Returns nil if N is less than 1." "-cons*" "-sum" "-product" + "-min" + "-min-by" + "--min-by" + "-max" + "-max-by" + "--max-by" )) (special-variables '( "it" diff --git a/dev/examples.el b/dev/examples.el index e035320..06105bd 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -109,6 +109,28 @@ (-product '(1)) => 1 (-product '(1 2 3)) => 6) +(defexamples -min + (-min 0) => 0 + (-min 1) => 1 + (-min 1 2 3) => 1) + +(defexamples -min-by + (-min-by 'identity '()) => nil + (-min-by 'identity '(1)) => 1 + (--min-by (cdr it) '((a . 1) (b . 2) (c . 3))) => '(a . 1) + (-min-by (lambda (x) (string-to-int x)) '("1" "2" "3")) => "1") + +(defexamples -max + (-max 0) => 0 + (-max 1) => 1 + (-max 1 2 3) => 3) + +(defexamples -max-by + (-max-by 'identity '()) => nil + (-max-by 'identity '(1)) => 1 + (--max-by (cdr it) '((a . 1) (b . 2) (c . 3))) => '(c . 3) + (-max-by (lambda (x) (string-to-int x)) '("1" "2" "3")) => "3") + (defexamples -any? (-any? 'even? '(1 2 3)) => t (-any? 'even? '(1 3 5)) => nil