6.1 序列

本节描述可以接受任意类型序列的函数。

Function: sequencep object

如果 object 是列表、向量、字符串、布尔向量或字符表,该函数返回 t,否则返回 nil。另见下面的 seqp

Function: length sequence

该函数返回 sequence 中的元素个数。如果参数不是序列或者是点列表(dotted list),函数会抛出 wrong-type-argument 错误;如果参数是循环列表(circular list),则抛出 circular-list 错误。对于字符表(char-table),返回的值总是比 Emacs 最大字符码大 1。

相关函数 safe-length,see Definition of safe-length

(length '(1 2 3))
    ⇒ 3
(length ())
    ⇒ 0
(length "foobar")
    ⇒ 6
(length [1 2 3])
    ⇒ 3
(length (make-bool-vector 5 nil))
    ⇒ 5

另见 string-bytes,位于 Text Representations 中。

如果你需要计算字符串在显示时的宽度,应当使用 string-width(see Size of Displayed Text),而非 length。因为 length 只统计字符个数,不会考虑每个字符的实际显示宽度。

Function: length< sequence length

sequence 的长度小于 length,返回非 nil 值。如果 sequence 是一个很长的列表,使用该函数会比先计算列表长度再比较更高效。

Function: length> sequence length

sequence 的长度大于 length,返回非 nil 值。

Function: length= sequence length

sequence 的长度等于 length,返回非 nil 值。

Function: elt sequence index

该函数返回 sequence 中由 index 索引的元素。index 的合法取值是从 0 到序列长度减一的整数。若 sequence 是列表,超出范围的索引行为与 nth 一致,See Definition of nth。其他情况下,超出范围的索引会触发 args-out-of-range 错误。

(elt [1 2 3 4] 2)
     ⇒ 3
(elt '(1 2 3 4) 2)
     ⇒ 3
;; We use string to show clearly which character elt returns.
(string (elt "1234" 2))
     ⇒ "3"
(elt [1 2 3 4] 4)
     error→ Args out of range: [1 2 3 4], 4
(elt [1 2 3 4] -1)
     error→ Args out of range: [1 2 3 4], -1

该函数是对 aref(see 操作数组的函数)和 nth(see Definition of nth)的通用化。

Function: copy-sequence seqr

该函数返回 seqr 的副本,seqr 应当是一个序列(sequence)或记录(record)。副本与原对象的类型完全相同,且包含与原对象顺序一致的相同元素。但如果 seqr 为空(例如长度为 0 的字符串或向量),该函数返回的值可能并非副本,而是与 seqr 类型相同、内容完全一致的空对象。

向副本中存入新元素不会影响原始的 seqr,反之亦然。但副本中的元素并非复制而来;它们与原对象的元素是完全相同的(通过 eq 判断为真)。因此,通过副本修改这些元素的内部内容时,对应的修改也会体现在原对象中。

若参数是带有文本属性(text properties)的字符串,则副本中的属性列表本身会被复制,不会与原字符串的属性列表共享。但属性的实际值仍为共享状态。See Text Properties

该函数不适用于点列表(dotted lists)。尝试复制循环列表(circular list)可能会导致无限循环。

有关复制序列的其他方法,另请参见 构建 cons 单元与列表 中的 append 函数、创建字符串 中的 concat 函数,以及 向量相关函数 中的 vconcat 函数。

(setq bar (list 1 2))
     ⇒ (1 2)
(setq x (vector 'foo bar))
     ⇒ [foo (1 2)]
(setq y (copy-sequence x))
     ⇒ [foo (1 2)]

(eq x y)
     ⇒ nil
(equal x y)
     ⇒ t
(eq (elt x 1) (elt y 1))
     ⇒ t

;; Replacing an element of one sequence.
(aset x 0 'quux)
x ⇒ [quux (1 2)]
y ⇒ [foo (1 2)]

;; Modifying the inside of a shared element.
(setcar (aref x 1) 69)
x ⇒ [quux (69 2)]
y ⇒ [foo (69 2)]
Function: reverse sequence

该函数会创建一个新的序列,其元素为 sequence 的元素,但排列顺序完全反转。原始参数 sequence 不会 被修改。请注意,字符表(char-tables)无法被反转。

(setq x '(1 2 3 4))
     ⇒ (1 2 3 4)
(reverse x)
     ⇒ (4 3 2 1)
x
     ⇒ (1 2 3 4)
(setq x [1 2 3 4])
     ⇒ [1 2 3 4]
(reverse x)
     ⇒ [4 3 2 1]
x
     ⇒ [1 2 3 4]
(setq x "xyzzy")
     ⇒ "xyzzy"
(reverse x)
     ⇒ "yzzyx"
x
     ⇒ "xyzzy"
Function: nreverse sequence

该函数会反转 sequence 中元素的排列顺序。与 reverse 函数不同的是,原始的 sequence 可能会被修改。

示例如下:

(setq x (list 'a 'b 'c))
     ⇒ (a b c)
x
     ⇒ (a b c)
(nreverse x)
     ⇒ (c b a)
;; The cons cell that was first is now last.
x
     ⇒ (a)

为避免产生混淆,我们通常会将 nreverse 函数的返回值重新存储到原本存放原始列表的同一个变量中:

(setq x (nreverse x))

以下是我们常用的示例 (a b c)nreverse 函数处理后的结果,附带图形化展示:

Original list head:                       Reversed list:
 -------------        -------------        ------------
| car  | cdr  |      | car  | cdr  |      | car | cdr  |
|   a  |  nil |<--   |   b  |   o  |<--   |   c |   o  |
|      |      |   |  |      |   |  |   |  |     |   |  |
 -------------    |   --------- | -    |   -------- | -
                  |             |      |            |
                   -------------        ------------

对于向量来说,操作更简单,因为你不需要使用 setq。

(setq x (copy-sequence [1 2 3 4]))
     ⇒ [1 2 3 4]
(nreverse x)
     ⇒ [4 3 2 1]
x
     ⇒ [4 3 2 1]

请注意,与 reverse 函数不同,本函数无法作用于字符串。尽管你可以通过 aset 函数修改字符串数据,但我们仍强烈建议你将字符串视为不可变对象 —— 即便它们本身具备可变特性。See 可变性

Function: sort sequence &rest keyword-args

该函数对 sequence 进行排序,该参数必须是列表或向量,并返回同类型的已排序序列。 该排序是稳定排序,即排序键相等的元素会保持它们原本的相对顺序。它接受下列可选关键字参数:

:key keyfunc

使用 keyfunc 生成用于比较的键值。keyfunc 是一个函数,接收 sequence 中的单个元素并返回其键值。如果未提供此参数,或 keyfuncnil,则默认使用 identity;即直接将元素本身作为排序键。

:lessp predicate

使用 predicate 对键进行排序。predicate 是一个接收两个排序键作为参数的函数,若第一个键应排在第二个之前,则返回非 nil。如果未提供此参数,或 predicatenil,则使用 value<。该函数适用于多种 Lisp 类型,通常按升序排序(see definition of value<,见下文)。

为保证一致性,所有谓词必须遵守以下规则:

  • 必须具有 antisymmetric反对称性:不能同时将 a 排在 b 之前且将 b 排在 a 之前。
  • 必须具有 传递性:如果将 a 排在 b 之前、b 排在 c 之前,则必须同样将 a 排在 c 之前。
:reverse flag

如果 flag 为非 nil,则反转排序顺序。在默认 :lessp 谓词下,这表示按降序排序。

:in-place flag

如果 flag 为非 nil,则对 sequence 进行原地排序(破坏性排序)并返回该序列。如果为 nil 或未提供此参数,则返回输入序列的排序副本,sequence 本身保持不变。原地排序速度稍快,但会丢失原序列。

如果默认行为不符合你的需求,通常提供一个新的 :key 函数,会比改用另一个 :lessp 谓词更简单、更高效。例如,考虑对这些字符串进行排序:

(setq numbers '("one" "two" "three" "four" "five" "six"))
(sort numbers)
     ⇒ ("five" "four" "one" "six" "three" "two")

你可以通过提供一个不同的键函数,转而按长度对这些字符串进行排序:

(sort numbers :key #'length)
     ⇒ ("one" "two" "six" "four" "five" "three")

请注意,得益于排序的稳定性,长度相同的字符串会保留其原始顺序。现在假设你想要按长度排序,但在长度相同时(出现并列时),再根据字符串内容来打破平局。最简单的方法是指定一个键函数,该函数能将元素转换为可按此规则排序的值。由于 value< 会按字典序对复合对象(点对、列表、向量和记录)进行排序,你可以这样做:

(sort numbers :key (lambda (x) (cons (length x) x)))
     ⇒ ("one" "six" "two" "five" "four" "three")

这是因为 (3 . "six") 排在 (3 . "two") 之前,依此类推。

为兼容旧版本 Emacs,sort 函数也支持以固定的双参数形式调用:

(sort sequence predicate)

其中 predicate 对应前述 :lessp 参数。使用该形式调用时,排序始终以原地方式执行。

有关更多执行排序操作的函数,see Sorting Text。关于 sort 函数的实用示例,可参见 Access to Documentation Strings 中对 documentation 函数的说明。

Function: value< a b

该函数会在 a 按标准排序规则应排在 b 之前时返回非 nil 值;这意味着,若 b 排在 a 之前、二者相等或无排序关系,函数会返回 nil

参数 ab 必须为同一类型。具体规则如下:

  • 数字通过 < 进行比较(see definition of <)。
  • 字符串通过 string-lessp 进行比较(see definition of string-lessp),符号则通过将其名称作为字符串比较来排序。
  • 点对、列表、向量和记录按字典序比较。具体来说,会从左到右逐元素比较两个序列,直至找到首个不同的元素对,最终结果即为该元素对经 value< 比较后的结果。若其中一个序列先遍历完所有元素,则较短的序列排在较长的序列之前。
  • 标记(marker)先按所属缓冲区(buffer)比较,再按位置(position)比较。
  • 缓冲区(buffer)和进程(process)通过将其名称作为字符串比较来排序。已失效的缓冲区(名称为 nil)会排在所有有效缓冲区之前。
  • 其他类型被视为无排序关系,函数返回值为 nil

Examples:

(value< -4 3.5) ⇒ t
(value< "dog" "cat") ⇒ nil
(value< 'yip 'yip) ⇒ nil
(value< '(3 2) '(3 2 0)) ⇒ t
(value< [3 2 "a"] [3 2 "b"]) ⇒ t

需要注意的是,nil 的处理方式取决于其比较对象:它会被视作符号(symbol)或空列表(empty list)二者其一:

(value< nil '(0)) ⇒ t
(value< 'nib nil) ⇒ t

可比较的序列(列表、向量等)长度没有限制,但如果使用 value< 比较循环结构或深度嵌套的数据结构,该函数可能会报错并失败。

seq.el 库提供了以下额外的序列操作宏和函数,均以 seq- 为前缀。

本库中定义的所有函数都无副作用;也就是说,它们不会修改你传入的任何序列(列表、向量或字符串)。除非另有说明,返回结果的类型与输入序列的类型相同。对于接收判定函数(predicate)的那些函数,该判定函数应是只接受一个参数的函数。

seq.el 库可以进行扩展,以支持更多类型的序列式数据结构。为此,所有函数均通过 cl-defgeneric 定义。有关如何使用 cl-defgeneric 进行扩展的更多细节,see 泛型函数

Function: seq-elt sequence index

该函数返回 sequence 中指定 index 位置的元素。index 为整数,其有效值范围是从 0 到 sequence 长度减 1。对于内置序列类型,若传入超出范围的索引值,seq-elt 的行为与 elt 一致。详细说明参见 Definition of elt

(seq-elt [1 2 3 4] 2)
⇒ 3

seq-elt 返回的位置可通过 setf 进行赋值(see setf)。

(setq vec [1 2 3 4])
(setf (seq-elt vec 2) 5)
vec
⇒ [1 2 5 4]
Function: seq-length sequence

该函数返回 sequence 中包含的元素个数。对于内置序列类型,seq-length 的行为与 length 一致。See Definition of length

Function: seqp object

object 是序列(列表或数组),或是通过 seq.el 通用函数定义的其他序列类型,则该函数返回非 nil 值。这是 sequencep 的可扩展变体。

(seqp [1 2])
⇒ t
(seqp 2)
⇒ nil
Function: seq-drop sequence n

该函数返回 sequence 中除前 n 个(n 为整数)元素之外的所有元素。若 n 为负数或零,则返回结果为 sequence 本身。

(seq-drop [1 2 3 4 5 6] 3)
⇒ [4 5 6]
(seq-drop "hello world" -4)
⇒ "hello world"
Function: seq-take sequence n

该函数返回 sequence 的前 n 个(n 为整数)元素。若 n 为负数或零,则返回结果为 nil

(seq-take '(1 2 3 4) 3)
⇒ (1 2 3)
(seq-take [1 2 3 4] 0)
⇒ []
Function: seq-take-while predicate sequence

该函数按顺序返回 sequence 中的元素,在第一个使 predicate 返回 nil 的元素处停止截取(即不包含该元素)。

(seq-take-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2))
⇒ (1 2 3)
(seq-take-while (lambda (elt) (> elt 0)) [-1 4 6])
⇒ []
Function: seq-drop-while predicate sequence

该函数按顺序返回 sequence 中的元素,从第一个使 predicate 返回 nil 的元素开始截取(包含该元素)。

(seq-drop-while (lambda (elt) (> elt 0)) '(1 2 3 -1 -2))
⇒ (-1 -2)
(seq-drop-while (lambda (elt) (< elt 0)) [1 4 6])
⇒ [1 4 6]
Function: seq-split sequence length

该函数返回一个列表,其中包含 sequence 被拆分后的若干子序列,每个子序列的长度最多为 length。(若 sequence 的长度并非 length 的整数倍,则最后一个子序列的长度可能小于 length。)

(seq-split [0 1 2 3 4] 2)
⇒ ([0 1] [2 3] [4])
Function: seq-do function sequence

该函数依次将 function 作用于 sequence 中的每个元素(此举通常是为了利用其副作用),并返回 sequence 本身。

Function: seq-map function sequence

该函数返回将 function 作用于 sequence 中每个元素后得到的结果,返回值为一个列表。

(seq-map #'1+ '(2 4 6))
⇒ (3 5 7)
(seq-map #'symbol-name [foo bar])
⇒ ("foo" "bar")
Function: seq-map-indexed function sequence

该函数会将 function 应用于 sequence 的每个元素及其在 seq 中的索引,并返回应用后的结果。返回值为一个列表。

(seq-map-indexed (lambda (elt idx)
                   (list idx elt))
                 '(a b c))
⇒ ((0 a) (1 b) (2 c))
Function: seq-mapn function &rest sequences

该函数会将 function 应用于 sequences 中的每组对应元素,并返回应用后的结果。function 的参数个数(参见 see subr-arity)必须与序列的数量相匹配。映射过程会在最短的序列遍历完毕时终止,返回值为一个列表。

(seq-mapn #'+ '(2 4 6) '(20 40 60))
⇒ (22 44 66)
(seq-mapn #'concat '("moskito" "bite") ["bee" "sting"])
⇒ ("moskitobee" "bitesting")
Function: seq-filter predicate sequence

该函数返回 sequence 中所有使 predicate 返回非 nil 值的元素组成的列表。

(seq-filter (lambda (elt) (> elt 0)) [1 -1 3 -3 5])
⇒ (1 3 5)
(seq-filter (lambda (elt) (> elt 0)) '(-1 -3 -5))
⇒ nil
Function: seq-remove predicate sequence

该函数返回 sequence 中所有使 predicate 返回 nil 值的元素组成的列表。

(seq-remove (lambda (elt) (> elt 0)) [1 -1 3 -3 5])
⇒ (-1 -3)
(seq-remove (lambda (elt) (< elt 0)) '(-1 -3 -5))
⇒ nil
Function: seq-remove-at-position sequence n

该函数返回 sequence 的一个副本,其中位于(从零开始计数的)索引 n 处的元素已被移除。返回结果的序列类型与 sequence 保持一致。

(seq-remove-at-position [1 -1 3 -3 5] 0)
⇒ [-1 3 -3 5]
(seq-remove-at-position [1 -1 3 -3 5] 3)
⇒ [1 -1 3 5]
Function: seq-keep function sequence

该函数返回一个列表,包含对 sequence 中的每个元素调用 function 后得到的所有非 nil 结果。

(seq-keep #'cl-digit-char-p '(?6 ?a ?7))
⇒ (6 7)
Function: seq-reduce function sequence initial-value

该函数的执行逻辑为:首先以 initial-valuesequence 的第一个元素为参数调用 function,接着以上一次调用的结果和 sequence 的第二个元素为参数调用 function,然后再以上一轮结果和 sequence 的第三个元素为参数调用 function,依此类推,最终返回最后一次调用 function 的结果。function 需为接收两个参数的函数。

调用 function 时会传入两个参数:initial-value(后续则为累计值)作为第一个参数,sequence 中的元素依次作为第二个参数。

sequence 为空序列,则不会调用 function,直接返回 initial-value

(seq-reduce #'+ [1 2 3 4] 0)
⇒ 10
(seq-reduce #'+ '(1 2 3 4) 5)
⇒ 15
(seq-reduce #'+ '() 3)
⇒ 3
Function: seq-some predicate sequence

该函数会依次将 predicate 应用于 sequence 的每个元素,并返回第一个由该断言函数返回的非 nil 值。

(seq-some #'numberp ["abc" 1 nil])
⇒ t
(seq-some #'numberp ["abc" "def"])
⇒ nil
(seq-some #'null ["abc" 1 nil])
⇒ t
(seq-some #'1+ [2 4 6])
⇒ 3
Function: seq-find predicate sequence &optional default

该函数返回 sequence 中首个使 predicate 返回非 nil 值的元素。若没有元素匹配该断言函数,则返回 default

需注意,若找到的元素与 default 的值完全相同,此函数会存在二义性 —— 这种情况下无法判断究竟是找到了匹配元素,还是根本没有找到任何匹配元素。

(seq-find #'numberp ["abc" 1 nil])
⇒ 1
(seq-find #'numberp ["abc" "def"])
⇒ nil
Function: seq-every-p predicate sequence

若将 predicate 应用于 sequence 的每一个元素后,返回结果均为非 nil 值,则该函数返回非 nil 值。

(seq-every-p #'numberp [2 4 6])
⇒ t
(seq-every-p #'numberp [2 4 "6"])
⇒ nil
Function: seq-empty-p sequence

sequence 为空序列,则该函数返回非 nil 值。

(seq-empty-p "not empty")
⇒ nil
(seq-empty-p "")
⇒ t
Function: seq-count predicate sequence

该函数返回 sequence 中使 predicate 返回非 nil 值的元素数量。

(seq-count (lambda (elt) (> elt 0)) [-1 2 0 3 -2])
⇒ 2
Function: seq-sort function sequence

该函数返回 sequence 的一个副本,该副本会根据 function 进行排序。其中 function 是一个接收两个参数的函数:若第一个参数应排在第二个参数之前,该函数需返回非 nil 值。

Function: seq-sort-by function predicate sequence

该函数与 seq-sort 功能类似,但在排序前,会先对 sequence 中的每个元素应用 function 进行转换。function 是一个接收单个参数的函数。

(seq-sort-by #'seq-length #'> ["a" "ab" "abc"])
⇒ ["abc" "ab" "a"]
Function: seq-contains-p sequence elt &optional function

sequence 中至少有一个元素与 elt 相等,则该函数返回非 nil 值。若可选参数 function 的值为非 nil,则会使用这个接收两个参数的函数来替代默认的 equal 函数进行比较。

(seq-contains-p '(symbol1 symbol2) 'symbol1)
⇒ t
(seq-contains-p '(symbol1 symbol2) 'symbol3)
⇒ nil
Function: seq-set-equal-p sequence1 sequence2 &optional testfn

该函数用于检查 sequence1sequence2 是否包含完全相同的元素(元素顺序不影响判断结果)。若可选参数 testfn 的值为非 nil,则会使用这个接收两个参数的函数,替代默认的 equal 函数进行元素比较。

(seq-set-equal-p '(a b c) '(c b a))
⇒ t
(seq-set-equal-p '(a b c) '(c b))
⇒ nil
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a"))
⇒ t
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a") #'eq)
⇒ nil
Function: seq-position sequence elt &optional function

该函数返回 sequence 中首个与 elt 相等的元素的(从零开始计数的)索引值。若可选参数 function 的值为非 nil,则会使用这个接收两个参数的函数,替代默认的 equal 函数进行元素比较。

(seq-position '(a b c) 'b)
⇒ 1
(seq-position '(a b c) 'd)
⇒ nil
Function: seq-positions sequence elt &optional testfn

该函数返回一个列表,其中包含 sequence 中满足以下条件的所有元素的(从零开始计数的)索引:将元素与 elt 作为参数传入 testfn 时,该函数返回非 nil 值。testfn 的默认值为 equal 函数。

(seq-positions '(a b c a d) 'a)
⇒ (0 3)
(seq-positions '(a b c a d) 'z)
⇒ nil
(seq-positions '(11 5 7 12 9 15) 10 #'>=)
⇒ (0 3 5)
Function: seq-uniq sequence &optional function

该函数返回 sequence 去除重复元素后的元素组成的列表。若可选参数 function 的值为非 nil,则会使用这个接收两个参数的函数,替代默认的 equal 函数来判定元素是否重复。

(seq-uniq '(1 2 2 1 3))
⇒ (1 2 3)
(seq-uniq '(1 2 2.0 1.0) #'=)
⇒ (1 2)
Function: seq-subseq sequence start &optional end

该函数返回 sequence 中从 startend(均为整数)的子序列(end 的默认值为序列最后一个元素的位置)。若 startend 为负数,则从 sequence 的末尾开始计数。

(seq-subseq '(1 2 3 4 5) 1)
⇒ (2 3 4 5)
(seq-subseq '[1 2 3 4 5] 1 3)
⇒ [2 3]
(seq-subseq '[1 2 3 4 5] -3 -1)
⇒ [3 4]
Function: seq-concatenate type &rest sequences

该函数返回一个类型为 type 的序列,该序列由 sequences 中的所有序列拼接而成。type 的可选值为:vector(向量)、list(列表)或 string(字符串)。

(seq-concatenate 'list '(1 2) '(3 4) [5 6])
⇒ (1 2 3 4 5 6)
(seq-concatenate 'string "Hello " "world")
⇒ "Hello world"
Function: seq-mapcat function sequence &optional type

该函数的执行逻辑为:先将 function 应用于 sequence 的每个元素并得到结果,再对该结果调用 seq-concatenate 函数,最终返回此次调用的结果。返回值为类型为 type 的序列;若 type 的值为 nil,则返回列表。

(seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)))
⇒ (1 2 3 4 5 6)
Function: seq-partition sequence n

该函数返回一个列表,其中包含将 sequence 的元素按长度 n 分组后得到的子序列。最后一个子序列包含的元素数量可能少于 nn 必须为整数;若 n 为负整数或 0,则返回值为 nil

(seq-partition '(0 1 2 3 4 5 6 7) 3)
⇒ ((0 1 2) (3 4 5) (6 7))
Function: seq-union sequence1 sequence2 &optional function

该函数返回一个列表,其中包含所有出现在 sequence1sequence2 中的元素。返回列表中的所有元素均为唯一值(即列表中任意两个元素经比较后都不会判定为相等)。若可选参数 function 的值为非 nil,则应使用这个接收两个参数的函数来比较元素,以替代默认的 equal 函数。

(seq-union [1 2 3] [3 5])
⇒ (1 2 3 5)
Function: seq-intersection sequence1 sequence2 &optional function

该函数返回一个列表,其中包含所有同时出现在 sequence1sequence2 中的元素。若可选参数 function 的值为非 nil,则会使用这个接收两个参数的函数来比较元素,以替代默认的 equal 函数。

(seq-intersection [2 3 4 5] [1 3 5 6 7])
⇒ (3 5)
Function: seq-difference sequence1 sequence2 &optional function

该函数返回一个列表,其中包含所有出现在 sequence1 中但未出现在 sequence2 中的元素。若可选参数 function 的值为非 nil,则会使用这个接收两个参数的函数来比较元素,以替代默认的 equal 函数。

(seq-difference '(2 3 4 5) [1 3 5 6 7])
⇒ (2 4)
Function: seq-group-by function sequence

该函数将 sequence 中的元素分组为一个关联列表(alist),该列表的键(key)是对 sequence 中的每个元素应用 function 后得到的结果。键的比较采用 equal 函数进行。

(seq-group-by #'integerp '(1 2.1 3 2 3.2))
⇒ ((t 1 3 2) (nil 2.1 3.2))
(seq-group-by #'car '((a 1) (b 2) (a 3) (c 4)))
⇒ ((b (b 2)) (a (a 1) (a 3)) (c (c 4)))
Function: seq-into sequence type

该函数将序列 sequence 转换为类型为 type 的序列。type 可以是以下符号之一:vector(向量)、string(字符串)或 list(列表)。

(seq-into [1 2 3] 'list)
⇒ (1 2 3)
(seq-into nil 'vector)
⇒ []
(seq-into "hello" 'vector)
⇒ [104 101 108 108 111]
Function: seq-min sequence

该函数返回 sequence(序列)中的最小元素。sequence 中的元素必须为数字或标记(marker,see Markers )。 This function returns the smallest element of sequence. The elements of sequence must be numbers or markers (see Markers).

(seq-min [3 1 2])
⇒ 1
(seq-min "Hello")
⇒ 72
Function: seq-max sequence

该函数返回 sequence(序列)中的最大元素。sequence 中的元素必须为数字或标记(marker)。

(seq-max [1 3 2])
⇒ 3
(seq-max "Hello")
⇒ 111
Macro: seq-doseq (var sequence) body…

该宏与 dolist(详见 dolist 章节)的功能类似,不同之处在于 sequence(序列)可以是列表(list)、向量(vector)或字符串(string)类型。该宏主要用于产生副作用(side-effects)场景。

Macro: seq-let var-sequence val-sequence body…

该宏会将 var-sequence(变量序列)中定义的变量,绑定到 val-sequence(值序列)中对应的元素值上。这种操作被称为 解构绑定(destructuring binding)var-sequence 中的元素本身也可以包含序列,从而支持嵌套解构。

var-sequence 序列中还可以包含 &rest 标记,其后紧跟一个变量名 —— 该变量会被绑定到 val-sequence 中剩余的所有元素上。

(seq-let [first second] [1 2 3 4]
  (list first second))
⇒ (1 2)
(seq-let (_ a _ b) '(1 2 3 4)
  (list a b))
⇒ (2 4)
(seq-let [a [b [c]]] [1 [2 [3]]]
  (list a b c))
⇒ (1 2 3)
(seq-let [a b &rest others] [1 2 3 4]
  others)
⇒ [3 4]

pcase 模式提供了另一种实现解构绑定的机制,详见 使用 pcase 模式进行解构 章节。

Macro: seq-setq var-sequence val-sequence

该宏的功能与 seq-let 类似,不同之处在于:它会以 setq 的方式为变量赋值,而非像 let 那样进行变量绑定。

(let ((a nil)
      (b nil))
  (seq-setq (_ a _ b) '(1 2 3 4))
  (list a b))
⇒ (2 4)
Function: seq-random-elt sequence

该函数随机返回 sequence(序列)中的一个元素。

(seq-random-elt [1 2 3 4])
⇒ 3
(seq-random-elt [1 2 3 4])
⇒ 2
(seq-random-elt [1 2 3 4])
⇒ 4
(seq-random-elt [1 2 3 4])
⇒ 2
(seq-random-elt [1 2 3 4])
⇒ 1

sequence(序列)为空,则该函数会触发一个错误。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike