>From dfa552f2e8b61ce301900dcce7da92d4f8f0854a Mon Sep 17 00:00:00 2001 From: Jarmo Hurri Date: Mon, 15 Oct 2012 09:54:24 +0300 Subject: [PATCH] Table lookup functions * lisp/org-table.el: added macro org-define-lookup-function and the calls to this macro that generate the lookup functions org-lookup-first, org-lookup-last and org-lookup-all * doc/org.texi: documented lookup functions --- doc/org.texi | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- lisp/org-table.el | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index c8f0afb..6d8f59a 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -378,6 +378,7 @@ The spreadsheet * Durations and time values:: How to compute durations and time values * Field and range formulas:: Formula for specific (ranges of) fields * Column formulas:: Formulas valid for an entire column +* Lookup functions:: Lookup functions for searching tables * Editing and debugging formulas:: Fixing formulas * Updating the table:: Recomputing all dependent fields * Advanced features:: Field and column names, parameters and automatic recalc @@ -2397,6 +2398,7 @@ formula, moving these references by arrow keys * Durations and time values:: How to compute durations and time values * Field and range formulas:: Formula for specific (ranges of) fields * Column formulas:: Formulas valid for an entire column +* Lookup functions:: Lookup functions for searching tables * Editing and debugging formulas:: Fixing formulas * Updating the table:: Recomputing all dependent fields * Advanced features:: Field and column names, parameters and automatic recalc @@ -2782,7 +2784,7 @@ can also be used to assign a formula to some but not all fields in a row. Named field, see @ref{Advanced features}. @end table address@hidden Column formulas, Editing and debugging formulas, Field and range formulas, The spreadsheet address@hidden Column formulas, Lookup functions, Field and range formulas, The spreadsheet @subsection Column formulas @cindex column formula @cindex formula, for table column @@ -2821,7 +2823,51 @@ stores it. With a numeric prefix argument(e.g.@: @kbd{C-5 C-c =}) the command will apply it to that many consecutive fields in the current column. @end table address@hidden Editing and debugging formulas, Updating the table, Column formulas, The spreadsheet address@hidden Lookup functions, Editing and debugging formulas, Column formulas, The spreadsheet address@hidden Lookup functions address@hidden lookup functions in tables address@hidden table lookup functions + +Org has three predefined Emacs Lisp functions for lookups in tables. address@hidden @code address@hidden (org-lookup-first VAL S-LIST R-LIST &optional PREDICATE) address@hidden org-lookup-first +Searches for the first element @code{S} in list @code{S-LIST} for which address@hidden +(PREDICATE VAL S) address@hidden lisp +is @code{t}; returns the value from the corresponding position in list address@hidden The default @code{PREDICATE} is @code{equal}. Note that the +parameters @code{VAL} and @code{S} are passed to @code{PREDICATE} in the same +order as the correspoding parameters are in the call to address@hidden, where @code{VAL} precedes @code{S-LIST}. If address@hidden is @code{nil}, the matching element @code{S} of @code{S-LIST} +is returned. address@hidden (org-lookup-last VAL S-LIST R-LIST &optional PREDICATE) address@hidden org-lookup-last +Similar to @code{org-lookup-first} above, but searches for the @i{last} +element for which @code{PREDICATE} is @code{t}. address@hidden (org-lookup-all VAL S-LIST R-LIST &optional PREDICATE) address@hidden org-lookup-all +Similar to @code{org-lookup-first}, but searches for @i{all} elements for +which @code{PREDICATE} is @code{t}, and returns @i{all} corresponding +values. This function can not be used by itself in a formula, because it +returns a list of values. However, powerful lookups can be built when this +function is combined with other Emacs Lisp functions. address@hidden table + +If the ranges used in these functions contain empty fields, the @code{E} mode +for the formula should usually be specified: otherwise empty fields will not be +included in @code{S-LIST} and/or @code{R-LIST} which can, for example, result +in an incorrect mapping from an element of @code{S-LIST} to the corresponding +element of @code{R-LIST}. + +These three functions can be used to implement associative arrays, count +matching cells, rank results, group data etc. For practical examples +see @uref{http://orgmode.org/worg/org-tutorials/org-lookups.html, this +tutorial on Worg}. + address@hidden Editing and debugging formulas, Updating the table, Lookup functions, The spreadsheet @subsection Editing and debugging formulas @cindex formula editing @cindex editing, of table formulas diff --git a/lisp/org-table.el b/lisp/org-table.el index 0555041..33fcb41 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -4875,6 +4875,38 @@ list of the fields in the rectangle ." (org-table-get-range (match-string 0 form) tbeg 1)) form))))))))) +(defmacro org-define-lookup-function (mode) + (let ((mode-str (symbol-name mode)) + (first-p (equal mode 'first)) + (all-p (equal mode 'all))) + (let ((plural-str (if all-p "s" ""))) + `(defun ,(intern (format "org-lookup-%s" mode-str)) (val s-list r-list &optional predicate) + ,(format "Find %s occurrence%s of VAL in S-LIST; return corresponding element%s of R-LIST. +If R-LIST is nil, return matching element%s of S-LIST. +If PREDICATE is not nil, use it instead of `equal' to match VAL. +Matching is done by (PREDICATE VAL S), where S is an element of S-LIST. +This function is generated by a call to the macro `org-define-lookup-function'." + mode-str plural-str plural-str plural-str) + (let ,(let ((lvars '((p (or predicate 'equal)) + (sl s-list) + (rl (or r-list s-list)) + (ret nil)))) + (if first-p (add-to-list 'lvars '(match-p nil))) + lvars) + (while ,(if first-p '(and (not match-p) sl) 'sl) + (progn + (if (funcall p val (car sl)) + (progn + ,(if first-p '(setq match-p t)) + (let ((rval (car rl))) + (setq ret ,(if all-p '(append ret (list rval)) 'rval))))) + (setq sl (cdr sl) rl (cdr rl)))) + ret))))) + +(org-define-lookup-function first) +(org-define-lookup-function last) +(org-define-lookup-function all) + (provide 'org-table) ;; Local variables: -- 1.7.7.6