Scheme/Chez Scheme 对象操作

Pairs and Lists

atom?

atom? 相当于 (lambda (x) (not (pair? x)))

(atom? '(a b c))  #f
(atom? '(3 . 4))  #f
(atom? '())  #t
(atom? 3)  #t

list-head(Chez)

用法:(list-head list n) n是一个非负整数,且小于等于list的长度;list-head和Scheme标准过程list-tail可能会同时使用来切割一个list,不同点在于,list-tail不会分配内存而只是返回源list的一个子列表,list-head总是返回源list前n个元素的副本

(list-head '(a b c) 0)  ()
(list-head '(a b c) 2)  (a b)
(list-head '(a b c) 3)  (a b c)
(list-head '(a b c . d) 2)  (a b)
(list-head '(a b c . d) 3)  (a b c)
(list-head '#1=(a . #1#) 5)  (a a a a a)

last-pair(Chez)

用法:(last-pair list) 列表不能为空。 last-pair返回列表的最后一对(pair)(不是最后一个元素), list可能是不正确的列表,在这种情况下,最后一对是包含最后一个元素和终止对象的一个pair。

(last-pair '(a b c d))  (d)
(last-pair '(a b c.d))  (c . d)

list-copy(Chez)

用法: (list-copy list) 返回一个list的副本,equal?(结构和值相同)判断为#t

list*(Chez)

用法:(list* obj … final-obj) 返回一个由obj … final-obj 组成的list, 与R6RS的**cons***相同

make-list(Chez)

用法: (make-list n) 或者 (make-list n obj) 返回n个对象的列表。n是一个正整数, 如果obj不指定,则返回的list是不确定的

 (make-list 0 '()) => ()
 (make-list 3 0) => (0 0 0)
 (make-list 2 "hi") => ("hi" "hi")

iota(Chez)

用法:(iota n) 返回从 0(包含)到 n(不包含)的整数列表,n须为精确的非负整数

(iota 0) => ()
(iota 5) => (0 1 2 3 4)

enumerate(Chez)

用法: (enumerate ls) 返回: 从 0(包含)到长度 ls(不包含)的整数列表

(enumerate '()) => ()
(enumerate '(a b c)) => (0 1 2)
(let ([ls '(a b c)])
	(map cons ls (enumerate ls))) => ((a . 0) (b . 1) (c . 2))

remq! | remv! | remove!(Chez)

用法: (remq! obj list) | (remv! obj list) | (remove! obj list) 返回: 列表中所有 obj 都被移除后的列表 这些过程与 R6RS 中的 remq, remv, 及 remove 过程类似,只是 remq!, remv! 和 remove! 使用输入列表中的pair来构成输出列表。它们进行较少的空间分配,但并不一定比它们非破坏性的相应版本更快。如果滥用,很容易导致混乱或错误的结果。

(remq! 'a '(a b a c a d))  (b c d)
(remv! #\a '(#\a #\b #\c)) => (#\b #\c)
(remove! '(c) '((a) (b) (c))) => ((a) (b))

substq | substv | subst | substq! | substv! | subst!(Chez)

用法: (subs* new old tree) 返回:在tree中将匹配到的old元素全部替换为new之后的tree. 对于 substq 和 substq! ,相等性测试是基于 eq?, substv 和 substv! 是基于 eqv?, 而 subst 和 subst! 是基于 equal? substq!, substv!, 和 subst! 执行破坏性的替换。它们进行较少的空间分配,但并不一定比它们非破坏性的对应版本更快。如果滥用,很容易导致混乱或错误的结果。

(substq 'a 'b '((b c) b a)) => ((a c) a a)

(substv 2 1 '((1 . 2) (1 . 4) . 1)) => ((2 . 2) (2 . 4) . 2)

(subst 'a
       '(a . b)
       '((a . b) (c a . b) . c)) => (a (c . a) . c)

(let ([tr '((b c) b a)])
  (substq! 'a 'b tr)
  tr) => ((a c) a a)

reverse!

用法:(reverse! list) 返回:将原list反向输出 reverse! 通过反转其链接破坏性地反向排序列表。以 reverse! 取代 reverse 减少了空间分配,但并不一定比使用 reverse 更快。如果滥用,会很容易导致混乱或错误的结果。

(reverse! '()) => ()
(reverse! '(a b c)) => (c b a)

(let ([x '(a b c)])
  (reverse! x)
  x) => (a)

(let ([x '(a b c)])
  (set! x (reverse! x))
  x) => (c b a)

append!

用法:(append! list …) 返回:将所有输入list串联起来的列表 如同 append, append! 返回一个新的列表,其中元素依次为第一个列表中的元素,第二个列表中的元素,第三个列表中的元素,等等。不同之处在于, append! 重用所有参数中的点对以构造新列表。即,每一个列表参数的最后一个cdr, 其后一元素变为指向下一个列表参数。除最后一个参数外,如果任一参数为空列表,它实质上会被忽略。最后一个参数(并不一定得是列表)是不变的。

相比于 append, append! 进行更少的空间分配(因为只修改指针,并没有数据拷贝),但并不一定更快。如果滥用,会很容易导致混乱或错误的结果。

(append! '(a b) '(c d)) => (a b c d)

(let ([x '(a b)])
  (append! x '(c d))
  x) => (a b c d)

(append '(1 2 (3 4)) '(5 6)) => (1 2 (3 4) 5 6)
(append '(1 2 (3 4)) '() '(5 6)) => (1 2 (3 4) 5 6)