に長さの異なる2つのリストをアップジップ:は、私は二つのリストを持っているelispの
(setq x (list "a" "b" "c"))
(setq y (list "1" "2" "3" "4"))
にはどうすればコンスセルリサイクル短いリストを(("a" . "1") ("b" . "2") ("c" . "3") ("a" . "4"))
のリストを作成することができますか?
に長さの異なる2つのリストをアップジップ:は、私は二つのリストを持っているelispの
(setq x (list "a" "b" "c"))
(setq y (list "1" "2" "3" "4"))
にはどうすればコンスセルリサイクル短いリストを(("a" . "1") ("b" . "2") ("c" . "3") ("a" . "4"))
のリストを作成することができますか?
あり、それを行うための簡単な方法は確かであるが、ここでは無限リストに入力シーケンスをオンバージョンだし、それらをzip圧縮:
(require 'cl-lib)
(cl-mapcar #'list (setcdr (last x) x) y)
I:ここで
(defun* cycle-iterator (xs &optional (idx 0) (len (length xs)))
"Create an iterator that will cycle over the elements in XS.
Return a cons, where the car is the current value and the cdr is
a function to continue the iteration."
(cons (nth (mod idx len) xs)
(eval `(lambda() (cycle-iterator ',xs ,(1+ idx) ,len)))))
(defun cycle-take (xs n)
"Take N elements from XS, cycling the elements if N exceeds the length of XS."
(loop
when (plusp n)
;; Creating the iterator returns the first value. Subsequent calls can then
;; be processed in a loop.
with (value . iterator) = (cycle-iterator xs)
with acc = (list value)
repeat (1- n) do (destructuring-bind (val . next) (funcall iterator)
(setq iterator next)
(setq acc (cons val acc)))
finally (return (nreverse acc))))
(defun cycling-zip (xs ys)
"Zip XS and YS together, cycling elements to ensure the result
is as long as the longest input list."
(loop
with limit = (max (length xs) (length ys))
for x in (cycle-take xs limit)
for y in (cycle-take ys limit)
collect (cons x y)))
;; Usage:
(cycling-zip '("a" "b" "c") '("1" "2" "3" "4"))
; => (("a" . "1") ("b" . "2") ("c" . "3") ("a" . "4"))
この回答は、dash
リスト操作ライブラリが必要です。あなたの問題を攻撃する前に、には、最長のリストの長さを見つけるのが良いです。私が思いついた最初の方法は次のとおりです。
(require 'dash)
(require 'dash-functional)
(length (-max-by (-on '> 'length) (list x y))) ; 4
-on
は、コンパレータを受け入れるパッケージdash-functional
からスマート機能、比較する上での鍵であり、このキーに比較する関数を返します。したがって、(-max-by (-on '> 'length) xs)
は、xs
の要素を見つけます。その要素のはです。しかし、この表現は自分自身にとってはあまりにもスマートです。dash-functional
は、字句的なスコープのためにEmacs 24でしか動作しません。 Python solutionに触発され、のは、それを書き換えてみましょう:
(-max (-map 'length (list x y))) ; 4
(-take n (-cycle xs))
を行い、無限cycledリストから最初のn
の要素を取ること。したがって、より小さなリストから要素が繰り返される連想リストを作成するには、書き込み:
(let ((len (-max (-map 'length (list x y)))))
(flet ((cycle (xs) (-take len (-cycle xs))))
(-zip (cycle x) (cycle y)))) ; (("a" . "1") ("b" . "2") ("c" . "3") ("a" . "4"))
私はlispのための自然に思えた再帰的なアプローチを行ってきました。
(defun zip (xs ys)
(cond
((or (null xs) (null ys))())
(t (cons (cons (car xs) (car ys)) (zip (cdr xs) (cdr ys))))))
実際には、循環リストがこの場合に役立つと思いました。それは変わらない... – RNA