From 2a7fbdc507e620d8de82d497d7ba0180b1a494c5 Mon Sep 17 00:00:00 2001 From: Fuco1 Date: Fri, 16 Aug 2013 18:41:27 +0200 Subject: [PATCH] Update -max-by & friends --- README.md | 56 ++++++++++++++++++++++----------------- dash.el | 70 ++++++++++++++++++++++--------------------------- dev/examples.el | 28 ++++++++++---------- 3 files changed, 78 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index 6261ac6..a0cab04 100644 --- a/README.md +++ b/README.md @@ -29,10 +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)` +* [-min](#-min-list) `(list)` +* [-min-by](#-min-by-comparator-list) `(comparator list)` +* [-max](#-max-list) `(list)` +* [-max-by](#-max-by-comparator-list) `(comparator list)` * [-any?](#-any-pred-list) `(pred list)` * [-all?](#-all-pred-list) `(pred list)` * [-none?](#-none-pred-list) `(pred list)` @@ -329,44 +329,52 @@ Return the product of `list`. (-product '(1 2 3)) ;; => 6 ``` -### -min `(x &rest xs)` +### -min `(list)` -Return the smallest value of all arguments. +Return the smallest value from `list` of numbers or markers. ```cl -(-min 0) ;; => 0 -(-min 1) ;; => 1 -(-min 1 2 3) ;; => 1 +(-min '(0)) ;; => 0 +(-min '(3 2 1)) ;; => 1 +(-min '(1 2 3)) ;; => 1 ``` -### -min-by `(pred list)` +### -min-by `(comparator list)` -Call `pred` for each item in `list` and return item with smallest value. +Take a comparison function `comparator` and a `list` and return +the least element of the list by the comparison function. + +See also combinator `-on` which can transform the values before +comparing them. ```cl -(-min-by 'identity '()) ;; => nil -(-min-by 'identity '(1)) ;; => 1 -(--min-by (cdr it) '((a . 1) (b . 2) (c . 3))) ;; => '(a . 1) +(-min-by '> '(4 3 6 1)) ;; => 1 +(-min-by (-on '> 'length) '((1 2 3) (1) (1 2))) ;; => '(1) +(-min-by (-on 'string-lessp 'int-to-string) '(2 100 22)) ;; => 22 ``` -### -max `(x &rest xs)` +### -max `(list)` -Return the largest value of all arguments. +Return the largest value from `list` of numbers or markers. ```cl -(-max 0) ;; => 0 -(-max 1) ;; => 1 -(-max 1 2 3) ;; => 3 +(-max '(0)) ;; => 0 +(-max '(3 2 1)) ;; => 3 +(-max '(1 2 3)) ;; => 3 ``` -### -max-by `(pred list)` +### -max-by `(comparator list)` + +Take a comparison function `comparator` and a `list` and return +the greatest element of the list by the comparison function. -Call `pred` for each item in `list` and return item with largest value. +See also combinator `-on` which can transform the values before +comparing them. ```cl -(-max-by 'identity '()) ;; => nil -(-max-by 'identity '(1)) ;; => 1 -(--max-by (cdr it) '((a . 1) (b . 2) (c . 3))) ;; => '(c . 3) +(-max-by '> '(4 3 6 1)) ;; => 6 +(-max-by (-on '> 'car) '((2 2 3) (3) (1 2))) ;; => '(3) +(-max-by (-on '> 'string-to-int) '("1" "2" "3")) ;; => "3" ``` ### -any? `(pred list)` diff --git a/dash.el b/dash.el index 51802bb..e70736d 100644 --- a/dash.el +++ b/dash.el @@ -906,47 +906,41 @@ 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)) +(defun -max (list) + "Return the largest value from LIST of numbers or markers." + (apply 'max list)) -(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)) +(defun -min (list) + "Return the smallest value from LIST of numbers or markers." + (apply 'min list)) + +(defun -max-by (comparator list) + "Take a comparison function COMPARATOR and a LIST and return +the greatest element of the list by the comparison function. + +See also combinator `-on' which can transform the values before +comparing them." + (--reduce (if (funcall comparator it acc) it acc) list)) + +(defun -min-by (comparator list) + "Take a comparison function COMPARATOR and a LIST and return +the least element of the list by the comparison function. + +See also combinator `-on' which can transform the values before +comparing them." + (--reduce (if (funcall comparator it acc) acc it) list)) (defmacro --max-by (form list) - "Anaphoric form of `-max-by'." - (declare (debug t)) - `(-max-by (lambda (it) ,form) ,list)) + "Anaphoric version of `-max-by'. + +The items for the comparator form are exposed as \"it\" and \"other\"." + `(-max-by (lambda (it other) ,form) ,list)) + +(defmacro --min-by (form list) + "Anaphoric version of `-min-by'. + +The items for the comparator form are exposed as \"it\" and \"other\"." + `(-min-by (lambda (it other) ,form) ,list)) (eval-after-load "lisp-mode" '(progn diff --git a/dev/examples.el b/dev/examples.el index d71de97..8c750eb 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -110,26 +110,26 @@ (-product '(1 2 3)) => 6) (defexamples -min - (-min 0) => 0 - (-min 1) => 1 - (-min 1 2 3) => 1) + (-min '(0)) => 0 + (-min '(3 2 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") + (-min-by '> '(4 3 6 1)) => 1 + (-min-by (-on '> 'length) '((1 2 3) (1) (1 2))) => '(1) + (-min-by (-on 'string-lessp 'int-to-string) '(2 100 22)) => 22 + (-min-by '< '(4 3 6 1)) => 6) (defexamples -max - (-max 0) => 0 - (-max 1) => 1 - (-max 1 2 3) => 3) + (-max '(0)) => 0 + (-max '(3 2 1)) => 3 + (-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") + (-max-by '> '(4 3 6 1)) => 6 + (-max-by (-on '> 'car) '((2 2 3) (3) (1 2))) => '(3) + (-max-by (-on '> 'string-to-int) '("1" "2" "3")) => "3" + (-max-by '< '(4 3 6 1)) => 1) (defexamples -any? (-any? 'even? '(1 2 3)) => t