Last active
August 29, 2015 14:19
-
-
Save xuchunyang/d9c21d029bd111f394ec to your computer and use it in GitHub Desktop.
elisp-sequence.el
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;;; Sequences | |
;; | |
;;; Types: | |
;; 1. list | |
;; 2. vector | |
;; 3. string | |
;; 4. bool-vector | |
;; 5. char-table | |
;; 6. `nil' | |
;; | |
;;; Functions: | |
;; * `sequencep' - sequence or not? | |
(mapcar #'sequencep '((1 2 3) | |
[1 2 3] | |
"123" | |
(make-bool-vector 5 nil) | |
nil | |
;; Other types | |
23 | |
'symbol | |
(lambda () nil))) ;; ==> (t t t t t nil t t) | |
;; * `length' - self-explanatory | |
(mapcar #'length '((1 2 3) | |
[1 2 3] | |
"123" | |
nil)) ;; ==> (2 3 3 0) | |
;; * `elt' - get an element from a sequence | |
(elt '(1 2 3 4) 2) ;; => 3 | |
(elt [1 2 3 4] 2) ;; => 3 | |
(string (elt "skin" 1)) ;; => "k" | |
(elt "skin" 23) ;; => Error (args-out-of-range "skin" 23) | |
;; * `copy-sequence' - self-explanatory | |
;; See also: `append' for list, `concat' for string and `vconcat' for vector | |
;; * `reverse' - reverse sequence, don't modify old sequence | |
(setq x '(1 2 3 4)) ;; => (1 2 3 4) | |
(reverse x) ;; => (4 3 2 1) | |
x ;; => (1 2 3 4) | |
(setq name user-full-name) ;; => "Chunyang Xu" | |
(reverse name) ;; => "uX gnaynuhC" | |
name ;; => "Chunyang Xu" | |
;; * `nreverse' - reverse sequence, may modify old sequence | |
(setq x '(1 2 3)) ;; => (1 2 3) | |
(nreverse x) ;; => (3 2 1) | |
x ;; => (1) | |
(setq x '(1 2 3)) ;; => (1 2 3) | |
(setq x (nreverse x)) ;; => (3 2 1) | |
x ;; => (3 2 1) | |
(setq x [1 2 3]) ;; => [1 2 3] | |
(nreverse x) ;; => [3 2 1] | |
x ;; => [3 2 1] | |
;; * `sort' - self-explanatory | |
(sort "abcd" #'<) ;; => Error (wrong-type-argument sequencep "abcd") | |
(sort '(1 2 3 2 4) '>=) ;; => (4 3 2 2 1) | |
(setq nums '(1 3 2 6 5 4 0)) ;; => (1 3 2 6 5 4 0) | |
;; Same as '(1 . (3 . (2 . (6 . (5 . (4 . (0 . nil))))))) | |
(sort nums #'<) ;; => (0 1 2 3 4 5 6) | |
nums ;; => (1 2 3 4 5 6) | |
(setq | |
vector | |
(vector '(8 . "xxx") '(9 . "aaa") '(8 . "bbb") '(9 . "zzz") | |
'(9 . "ppp") '(8 . "ttt") '(8 . "eee") '(9 . "fff"))) | |
;; => [(8 . "xxx") | |
;; (9 . "aaa") | |
;; (8 . "bbb") | |
;; (9 . "zzz") | |
;; (9 . "ppp") | |
;; (8 . "ttt") | |
;; (8 . "eee") | |
;; (9 . "fff")] | |
(sort vector (lambda (x y) (< (car x) (car y)))) | |
;; => [(8 . "xxx") | |
;; (8 . "bbb") | |
;; (8 . "ttt") | |
;; (8 . "eee") | |
;; (9 . "aaa") | |
;; (9 . "zzz") | |
;; (9 . "ppp") | |
;; (9 . "fff")] | |
;; A real example from | |
;; [[info:elisp#Accessing%20Documentation][info:elisp#Accessing Documentation]] | |
(defun describe-symbols (pattern) | |
"Describe the Emacs Lisp symbols matching PATTERN. | |
All symbols that have PATTERN in their name are described | |
in the *Help* buffer." | |
(interactive "sDescribe symbols matching: ") | |
(let ((describe-func | |
(function | |
(lambda (s) | |
;; Print description of symbol. | |
(if (fboundp s) ; It is a function. | |
(princ | |
(format "%s\t%s\n%s\n\n" s | |
(if (commandp s) | |
(let ((keys (where-is-internal s))) | |
(if keys | |
(concat | |
"Keys: " | |
(mapconcat 'key-description | |
keys " ")) | |
"Keys: none")) | |
"Function") | |
(or (documentation s) | |
"not documented")))) | |
(if (boundp s) ; It is a variable. | |
(princ | |
(format "%s\t%s\n%s\n\n" s | |
(if (custom-variable-p s) | |
"Option " "Variable") | |
(or (documentation-property | |
s 'variable-documentation) | |
"not documented"))))))) | |
sym-list) | |
;; Build a list of symbols that match pattern. | |
(mapatoms (function | |
(lambda (sym) | |
(if (string-match pattern (symbol-name sym)) | |
(setq sym-list (cons sym sym-list)))))) | |
;; Display the data. | |
(help-setup-xref (list 'describe-symbols pattern) (interactive-p)) | |
(with-help-window (help-buffer) | |
(mapcar describe-func (sort sym-list 'string<))))) | |
;; * `seq-drop' sequencep n - remove first N elements | |
(seq-drop [1 2 3 4 5] 3) ;; => [4 5] | |
(seq-drop "hello world" 3) ;; => "lo world" | |
(substring "hello world" 3) ;; => "lo world" | |
(seq-drop [1 2 3] -2) ;; => [1 2 3] | |
;; * `seq-take' - take first N elements | |
(seq-take '(1 2 3 4) 3) ;; => (1 2 3) | |
;; * `seq-drop-while' - drop from beg to end, stop if failed | |
(seq-drop-while (lambda (elt) (> elt 0)) [1 2 3 -1 -2 4]) ;; => [-1 -2 4] | |
;; * `seq-take-while' - take from beg to end, stop if failed | |
(seq-take-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2 4)) ;; => (1 2 3) | |
;; * `seq-filter' | |
(seq-filter #'integerp [-1 0 1 3.14 "skin"]) ;; => (-1 0 1) | |
;; * `seq-remove' | |
(seq-remove #'integerp [-1 0 1 3.14 "skin"]) ;; => (3.14 "skin") | |
;; * `seq-reduce' func seq init-val | |
(seq-reduce #'+ [1 2 3 4] 1000) ;; => 1010 | |
;; (+ 1) => 1 | |
;; (+ 1 2) => 3 | |
;; (+ 3 3) => 6 | |
;; (+ 6 4) => 10 | |
;; (+ 10 1000) => 1010 | |
;; * `seq-some-p' predicate seq - return first element for which predicate gets | |
;; * non-`nil' | |
(seq-some-p #'integerp ["skin" 3.14 10 23]) ;; => 10 | |
;; * `seq-every-p' predicate seq - check everyone | |
(seq-every-p #'numberp [1 2 3 ?c]) ;; => t | |
(seq-every-p #'stringp [1 2 "skin"]) ;; => nil | |
;; * `seq-empty-p' seq | |
(seq-empty-p "not empty") ;; => nil | |
(seq-empty-p "") ;; t | |
;; * `seq-count' predicate seq | |
(seq-count (lambda (elt) (> elt 0)) [-1 2 3 0 4]) ;; => 3 | |
;; * `seq-sort' | |
(setq a [1 2 0 4]) | |
(seq-sort #'> a) ;; => [4 2 1 0] | |
(let ((a '(1 0 2))) | |
(seq-sort #'< a) | |
a) ;; => (1 0 2) | |
;; * `seq-contains-p' seq &optional func, use `equal' by default if func is | |
;; nil. | |
(seq-contains-p '((1 2) 3 4) '(1 2)) ;; => (1 2) | |
(seq-contains-p '((1 2) 3 4) '(1 2) #'eq) ;; => nil | |
;; * `seq-uniq' seq &optional func-- remove duplicates, use `equal' by default | |
;; if func is nil. | |
(seq-uniq '(1 2 2.0 1.0)) ;; => (1 2 2.0) | |
(seq-uniq '(1 2 2.0 1.0) #'=) ;; => (1 2) | |
;; * `seq-subseq' | |
(seq-subseq '(1 2 3 4 5) 1 3) ;; => (2 3) | |
;; * `seq-concatenate' | |
(seq-concatenate 'list '(1 2) '(3 4)) ;; => (1 2 3 4) | |
(seq-concatenate 'string "hello" " " "world") ;; => "hello world" | |
;; * `seq-mapcat' | |
(seq-mapcat #'seq-reverse '((1 3 2) (6 2 9))) ;; => (2 3 1 9 2 6) | |
;; * `seq-partition' | |
(seq-partition '(0 1 2 3 4 5) 2) | |
;; => ((0 1) | |
;; (2 3) | |
;; (4 5)) | |
;; * `seq-intersection' seq1 seq2 &optional func | |
(seq-intersection [2 3 4 4] [1 2 3]) ;; => (2 3) | |
(seq-intersection [1.0 2 3] [1 2 4]) ;; => (2) | |
(seq-intersection [1.0 2 3] [1 2 4] #'=) ;; => (1.0 2) | |
;; * `seq-difference' seq1 seq2 &optional func | |
(seq-difference '(2 3 4 5) [1 2 5 6 7]) ;; => (3 4) | |
;; * `seq-group-by' func seq | |
(seq-group-by #'integerp '(1 2 3.14 5)) | |
;; => ((nil 3.14) | |
;; (t 1 2 5)) | |
(seq-group-by #'car '((a 1) | |
(b 2) | |
(c 3))) | |
;; => ((a | |
;; (a 1)) | |
;; (b | |
;; (b 2)) | |
;; (c | |
;; (c 3))) | |
;; * `seq-into' - convert seq type | |
(seq-into [1 2 3] 'list) ;; => (1 2 3) | |
(seq-into '(1 2 3) 'vector) ;; => [1 2 3] | |
(seq-into "hello" 'vector) ;; => [104 101 108 108 111] | |
;; * `seq-doseq' (var seq [result]) body_ | |
(setq res 0) ;; => 0 | |
(seq-doseq (var [1 2 3]) | |
(setq res (+ var res))) ;; => nil | |
res ;; => 6 | |
;;; Created: 2015/04/14 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment