programing

Clojure에서는 목록 위에 벡터를 사용하고 그 반대의 경우에는 벡터를 사용해야 합니까?

oldcodes 2023. 5. 9. 23:00
반응형

Clojure에서는 목록 위에 벡터를 사용하고 그 반대의 경우에는 벡터를 사용해야 합니까?

벡터는 seq가 아니라 lists가 seq라고 읽었습니다.저는 하나를 다른 하나에 사용하는 이유가 무엇인지 잘 모르겠습니다.벡터가 가장 많이 사용되는 것 같은데, 이유가 있나요?

다시 한 번 말하지만, 저는 참을성이 없어서 프리노드의 #clojure에서 질문함으로써 제 자신의 질문에 대답한 것 같습니다.자신의 질문에 대답하는 것이 좋은 것은 Stackoverflow.com 에서 권장됩니다. :D

저는 리치 히키와 간단한 논의를 나눴습니다. 그리고 여기 그 요지가 있습니다.

[12:21] <Raynes>    Vectors aren't seqs, right?
[12:21] <rhickey>   Raynes: no, but they are sequential
[12:21] <rhickey>   ,(sequential? [1 2 3])
[12:21] <clojurebot>    true
[12:22] <Raynes>    When would you want to use a list over a vector?
[12:22] <rhickey>   when generating code, when generating back-to-front
[12:23] <rhickey>   not too often in Clojure

Java 프로그래밍을 많이 하고 Java 수집 프레임워크에 익숙하다면 다음과 같은 목록을 생각해 보십시오.LinkedList그리고 벡터와 같은 것.ArrayList따라서 거의 같은 방식으로 용기를 선택할 수 있습니다.

추가적인 설명을 위해: 항목을 시퀀스의 앞이나 뒤에 개별적으로 추가하려는 경우, 연결된 목록이 벡터보다 훨씬 낫습니다. 항목을 매번 섞을 필요가 없기 때문입니다.그러나 목록의 앞이나 뒤가 아닌 특정 요소(예: 임의 액세스)를 자주 사용하려면 벡터를 사용해야 합니다.

그런데, 벡터는 쉽게 seq로 바뀔 수 있습니다.

user=> (def v (vector 1 2 3))
#'user/v
user=> v
[1 2 3]
user=> (seq v)
(1 2 3)
user=> (rseq v)
(3 2 1)

벡터는 O(1)개의 랜덤 액세스 시간을 가지지만 사전 할당되어야 합니다.목록은 동적으로 확장할 수 있지만 임의 요소에 액세스하는 것은 O(n)입니다.

벡터를 사용하는 경우:

  • 인덱싱된 액세스 성능 - 인덱싱된 액세스의 경우 ~O(1) 비용이 발생하고 목록의 경우 O(n) 비용이 발생합니다.
  • 추가 - conjis 포함 ~O(1)
  • 편리한 표기법 - 나는 문자 그대로의 목록을 위해 '(1 2 3)보다 [1 2 3]을 타이핑하고 읽는 것이 둘 다 더 쉽다고 생각합니다.

목록을 사용할 때:

  • 시퀀스로 액세스하려는 경우(목록이 새 개체를 할당할 필요 없이 seq를 직접 지원하므로)
  • 추가 중 - 목록의 시작 부분에 cons 또는 가급적 consis O(1)로 추가

간단한 참고 사항:

"벡터는 seq가 아니라 lists가 seq라고 읽었습니다."

시퀀스는 목록이나 벡터(또는 맵 또는 세트)보다 더 일반적입니다.
유감스럽게도 REPL은 목록과 시퀀스를 동일하게 인쇄합니다. 목록이 서로 다르더라도 실제로는 시퀀스인 것처럼 보이게 하기 때문입니다.(seq) 함수는 목록을 포함한 많은 다른 것들로부터 시퀀스를 만들 것이고, 그리고 나서 당신은 그 시퀀스를 seq들과 함께 복잡한 것들을 하는 모든 함수들에 공급할 수 있습니다.

user> (class (list 1 2 3))
clojure.lang.PersistentList

user> (class (seq (list 1 2 3)))
clojure.lang.PersistentList

user> (class (seq [1 2 3]))
clojure.lang.PersistentVector$ChunkedSeq

Sec에는 이미 seq인 경우 인수를 반환하는 바로 가기가 있습니다.

user> (let [alist (list 1 2 3)] (identical? alist (seq alist)))
true
user> (identical? (list 1 2 3) (seq (list 1 2 3)))
false

static public ISeq seq(Object coll){
        if(coll instanceof ASeq)
                return (ASeq) coll;
        else if(coll instanceof LazySeq)
                return ((LazySeq) coll).seq();
        else
                return seqFrom(coll);
}

리스트는 시퀀스이지만 다른 것도 마찬가지이며 모든 시퀀스가 리스트는 아닙니다.

언급URL : https://stackoverflow.com/questions/1147975/in-clojure-when-should-i-use-a-vector-over-a-list-and-the-other-way-around

반응형