6

リスト内の連続するペアをループする必要がある場合があります。私が今それをする方法は

(loop for x on lst while (not (null (cdr x)))
       (do something on (car x) and (cadr x)))

これを行うためのより良い/組み込みの方法があるかどうか疑問に思っています。

これが必要な理由は、たとえば、連続するペアを追加する関数などです。

(1 2 3 4 5) ----> (3 5 7 9)

これを取得できるreduceのような組み込み関数はありますか?

4

2 に答える 2

7

AFAIK、あなたがやりたいことをするための組み込み関数はありません。と一緒に何かをまとめようとすることもできますmaplistが、私の最初の本能はそれにも手を伸ばすことloopです。

あなたがそこに持っているものについてのほんの2、3のメモ。まず、非値はブール演算によって扱われるため、CLの場合(not (null foo))と同等です。第二に、その引数を分解することができます。つまり、これをよりエレガントに書くことができます。fooNILtloop

(loop for (a b) on lst while b
      collect (+ a b))

バージョンは次のmaplistようになります

(maplist 
   (lambda (rest) 
     (when (cdr rest) 
        (+ (first rest) (second rest)))
   lst)

これは読みにくいと思います(これにより、結果の前で終了するのではなく、結果の最後の要素としてNILも返されます)。

于 2012-08-10T17:04:23.363 に答える
3

Paul Grahamには、これを行うOnLispのmap-tupleという名前の関数があると思います。cdr、cddr、または任意の方法でリストを下に移動できます。これがコメント付きのバージョンです。マクロ aifの場合は照応を使用します。

(defun map-tuple (someList f &optional (by #'cdr))
 "(map-tuple someList f &optional (by #'cdr))
   f is a function that takes two args, returns one val (maybe)
   the map-tuple will collect all non-nil results in a list.
    example: 
(map-tuple '(1 2 3 4 5 6) (lambda (a b) (format T \"a: ~A b:~A~%\" a b)) #'cdr) 
a: 1 b:2
a: 2 b:3
a: 3 b:4
a: 4 b:5
a: 5 b:6
a: 6 b:NIL

(map-tuple '(1 2 3 4 5 6) (lambda (a b) (format T \"a: ~A b:~A~%\" a b)) #'cddr) 
a: 1 b:2
a: 3 b:4
a: 5 b:6
"
  (cond ((null someList)
        nil)
    (T
       (aif (funcall f (car someList) (cadr someList))
          (cons it (map-tuple (funcall by someList) f by))
           (map-tuple (funcall by someList) f by)))))
于 2012-08-23T06:43:31.597 に答える