Common Lisp loop-macro也可以收集休息

时间:2015-04-05 16:16:48

标签: loops split common-lisp sequence

我想使用LOOP拆分序列。 我认为最简单的方法是收集所有元素的循环,但这似乎不可能用循环。 看起来会这样:

(loop for i in '(1 2 3 4 5) with-rest rest
      if (not (= i 3))
      collect i
      else
      return (values i rest))

它应返回值(1 2)(3 4 5)(或者(4 5)作为第二个值)。 循环中是否有关键字可以执行此操作(或在迭代系统中),或者这只能通过编写新宏(或使用标记实体)来实现?

2 个答案:

答案 0 :(得分:3)

LOOP可以将列表拆分为头部和尾部。然后一个人不会使用in,而是on。您也可以收集变量。

CL-USER 13 > (loop for (i . rest) on '(1 2 3 4 5)
                   if (not (= i 3))
                   collect i into head
                   else return (values head (cons i rest)))
(1 2)
(3 4 5)

CL-USER 16 > (loop with list = '(1 2 3 4 5)
                   for i in list
                   for rest on (rest list)
                   if (not (= i 3))
                   collect i into head
                   else return (values head (cons i rest)))
(1 2)
(3 4 5)

答案 1 :(得分:2)

一个简洁的选项可以避免循环,但会遍历列表的一部分两次:

(let ((tail (member 3 list)))
  (values (ldiff tail list) tail))