diff options
author | Jarmo Hurri <jarmo.hurri@syk.fi> | 2012-10-15 09:54:24 +0300 |
---|---|---|
committer | Bastien Guerry <bzg@altern.org> | 2012-10-24 14:59:33 +0200 |
commit | e375cfd834b8cd9acc47b396578f32ca2cca6632 (patch) | |
tree | c78e8c70ee79d406684baf0a2c6a3abe710753f2 | |
parent | 1886af4337e802806ff8873822ccbd2e3763aa07 (diff) | |
download | org-mode-e375cfd834b8cd9acc47b396578f32ca2cca6632.tar.gz |
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
-rw-r--r-- | doc/org.texi | 50 | ||||
-rw-r--r-- | lisp/org-table.el | 32 |
2 files changed, 80 insertions, 2 deletions
diff --git a/doc/org.texi b/doc/org.texi index 4d20e06..4de6bfe 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 -@node Column formulas, Editing and debugging formulas, Field and range formulas, The spreadsheet +@node 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 -@node Editing and debugging formulas, Updating the table, Column formulas, The spreadsheet +@node Lookup functions, Editing and debugging formulas, Column formulas, The spreadsheet +@subsection Lookup functions +@cindex lookup functions in tables +@cindex table lookup functions + +Org has three predefined Emacs Lisp functions for lookups in tables. +@table @code +@item (org-lookup-first VAL S-LIST R-LIST &optional PREDICATE) +@findex org-lookup-first +Searches for the first element @code{S} in list @code{S-LIST} for which +@lisp +(PREDICATE VAL S) +@end lisp +is @code{t}; returns the value from the corresponding position in list +@code{R-LIST}. 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 +@code{org-lookup-first}, where @code{VAL} precedes @code{S-LIST}. If +@code{R-LIST} is @code{nil}, the matching element @code{S} of @code{S-LIST} +is returned. +@item (org-lookup-last VAL S-LIST R-LIST &optional PREDICATE) +@findex org-lookup-last +Similar to @code{org-lookup-first} above, but searches for the @i{last} +element for which @code{PREDICATE} is @code{t}. +@item (org-lookup-all VAL S-LIST R-LIST &optional PREDICATE) +@findex 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. +@end 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}. + +@node 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: |