ベクターにマップしてベクターを取得するにはどうすればよいですか?


15

私が見つけた唯一の機能は

(eval `(vector ,@(mapcar #'1+ [1 2 3 4])))
=> [2 3 4 5]

それはそうです遠く、あまりにも「正しい」方法であることが複雑。

回答:


19

cl-map代わりにを使用してください:

(cl-map 'vector #'1+ [1 2 3 4])

少し余分な背景は:cl-mapあるのCommon Lisp map関数は、シーケンス型に一般こと:

(cl-map 'vector #'1+ '[1 2 3 4]) ;; ==> [2 3 4 5]
(cl-map 'list   #'1+ '(1 2 3 4)) ;; ==> (2 3 4 5)
(cl-map 'string #'upcase "abc")  ;; ==> "ABC"

また、シーケンスタイプ間で変換することもできます(たとえば、ここでは、入力はリストであり、出力はベクトルです)。

(cl-map 'vector #'1+ '(1 2 3 4)) ;; ==> [2 3 4 5]

1
18秒で「勝者」:) clライブラリはコンパイラ警告を発しませんか?(主にFSFが不快なためですか?)
ショーン・オールレッド14年

1
FWIW、バイトコンパイルの問題はcl、再調整されたcl-libライブラリではなく、古いライブラリに関連していたと思います。私は、例えば、警告時にI得ることはありません(defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))し、その後に(byte-compile 'fnx)
ダン

2
互換性のあるcl-libを使用している場合でも、古いemacs(24.2)で警告が表示されると思います。私はそれについて心配しませんが、あなたはあなたの戦いを選ばなければなりません。
マラバルバ14年

16

私は18秒もbeatられたので、clライブラリなしでこれを行うより簡単で安全な方法があります。また、要素を評価しません。

(apply #'vector (mapcar #'1+ [1 2 3 4])) ;; => [2 3 4 5]

それもいいね!Re:古いEmacsについての以前のコメント:レガシーユーザーを予測する必要がある場合、特に役立ちそうです。いくつかの場所でのみ使用する必要がある場合に最も役立ちそうです。その時点で、cl-lib依存関係を回避することに対するわずかな不便をトレードオフできます。
ダン

1
とても気の利いた!! を使用することを考えていませんでしたapply
ショーンオールレッド14年

私は(apply #'vector ...)これまでに少し速くなると思いますが、完全を期すためにに置き換えることもできます(vconcat ...)
バジル

1

元のベクターがその後不要になり、メモリーの割り当てがタイムクリティカルである(たとえば、ベクターが大きい)場合には、それほどエレガントではないインプレースバリアントです。

(setq x [1 2 3 4])

(cl-loop for var across-ref x do
         (setf var (1+ var)))

結果はに保存されxます。x最後にフォームを返す必要がある場合はfinally return x、次のように追加できます。

(cl-loop for var across-ref x do
         (setf var (1+ var))
         finally return x)

1

完全を期すために、次を使用しseqます。

(require 'seq)
(seq-into (seq-map #'1+ [1 2 3 4]) 'vector)

Fólkvangr2018-11-12からは、まったく同じseq-into行で削除された回答があります。ユーザーは、以下の理由のために彼の答えを削除しました:「seqのライブラリーは、基盤となるCommon Lispの拡張を使用しているため、私のソリューションはあまり関係あり- 8時53分でフォールクヴァング5月16日を。」
トビアス

@トバイアス私はその論理に同意しないと思います。とにかくすべてがvconcatまたはvectorを使用することになりますが、異なるインターフェイスパラダイムは記録しておくと便利です。
ショーンオールレッド

問題ない。削除されたFólkvangrの回答が(ほぼ)あなたのものと一致するのを見て、通知したかったのです。何らかの理由で削除された答えを見ることは10000担当者:-(が必要です。
トビアス

@Tobiasええ、私はそれらの特権がサイト固有のものである理由を本当に理解したことはありませんでした:
ショーン・

0

ループを使用できます

(let ((v (vector 1 2 3 4)))
  (dotimes (i (length v))
    (aset v i (1+ (aref v i))))
  v)
;; => [2 3 4 5]

元のベクトルを変更したくない場合は、コピーを作成できます

(let* ((v0 (vector 1 2 3 4))
       (v (copy-sequence v0)))
  (dotimes (i (length v))
    (aset v i (1+ (aref v i))))
  (list v0 v))
;; => ([1 2 3 4] [2 3 4 5])

または、最初から新しいベクトルを作成します

(let* ((v0 (vector 1 2 3 4))
       (v (make-vector (length v0) nil)))
  (dotimes (i (length v))
    (aset v i (1+ (aref v0 i))))
  (list v0 v))
;; => ([1 2 3 4] [2 3 4 5])
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.