벡터를 매핑하고 벡터를 얻으려면 어떻게해야합니까?


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가 불분명하기 때문에?)
Sean Allred

1
FWIW, 바이트 컴파일 문제는 재 cl동기화 된 라이브러리가 아닌 이전 라이브러리 와 관련이 있다고 생각합니다 cl-lib. 예를 들어, 나는 (defun fnx () (cl-map 'vector #'1+ '[1 2 3 4]))그때에 경고를받지 않습니다 (byte-compile 'fnx).
Dan

2
cl-lib 호환성을 사용하더라도 이전 emacs (24.2)에 대한 경고가 표시됩니다. 그래도 걱정하지 않아도됩니다. 전투를 선택해야합니다.
Malabarba

16

내가 18 초 뛰었으므로 cl 라이브러리없이 간단하고 안전하게 할 수있는 방법이 있습니다. 또한 요소를 평가하지 않습니다.

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

그것은 또한 아주 좋습니다! Re : 이전 Emacs에 대한 이전 의견 : 레거시 사용자를 예상해야하는 경우 특히 도움이됩니다. 두 지점에서만 사용해야하는 경우 가장 유용합니다.이 시점에서 cl-lib종속성 을 피하는 것과 약간의 불편 함을 줄일 수 있습니다 .
Dan

1
매우 근사한 !! 나는을 사용하는 것에 대해 생각하지 않았다 apply.
Sean Allred

나는 (apply #'vector ...)조금 더 빠를 것이라고 생각 하지만, 완전성을 위해로 바꿀 수도 있습니다 (vconcat ...).
바질

1

원래 벡터가 더 이상 필요하지 않고 메모리 할당이 시간 결정적인 경우 (예를 들어, 벡터가 큰 경우)에 대해 그다지 우아하지 않은 inplace-variant입니다.

(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ólkvangr 2018-11-12 에서 똑같은 seq-into줄로 삭제 된 답변이 있습니다 . 사용자는 다음과 같은 이유로 자신의 답변을 삭제했습니다. "seq 라이브러리는 기본 Common Lisp 확장을 사용하기 때문에 관련성이 떨어집니다. – Fólkvangr May 16 at 8:53"
Tobias

@ Tobias 나는 그 논리에 동의하지 않는 것 같아요. 어쨌든 vconcat 또는 vector를 사용하여 모든 것이 끝나지 만 다른 인터페이스 패러다임은 기록에 유용합니다.
Sean Allred 10

문제 없어요. 방금 당신과 일치하는 Fólkvangr (거의)의 삭제 된 답변을보고 당신에게 알리고 싶었습니다. 어떤 이유로 든 삭제 된 답변을 보려면 10000 회답이 필요합니다
Tobias

@Tobias 네, 왜 그런 특권이 사이트에 특유한지 이해하지 못했습니다.
Sean Allred

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.