Skip to content

Instantly share code, notes, and snippets.

@xuchunyang
Last active August 29, 2015 14:19
Show Gist options
  • Save xuchunyang/d9c21d029bd111f394ec to your computer and use it in GitHub Desktop.
Save xuchunyang/d9c21d029bd111f394ec to your computer and use it in GitHub Desktop.
elisp-sequence.el
;;; 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