Clojure에서 목록 유형간에 쉽게 변환 할 수있는 방법이 있습니까?


92

벡터를 원할 때 lazy list를 사용하는 경우가 많으며 그 반대의 경우도 마찬가지입니다. 또한, 가끔은 맵 세트가 정말로 필요할 때 맵 벡터가 있습니다. 이러한 유형간에 변환하는 데 도움이되는 도우미 함수가 있습니까?

답변:


146

신뢰할 수있는 old intoseq가능한 모든 것 (list, vector, map, set, sorted-map)과 채우려는 빈 컨테이너를 가져 와서 넣을 수 있다는 것을 잊지 마십시오 into.

(into [] '(1 2 3 4)) ==> [1 2 3 4]         "have a lazy list and want a vector"
(into #{} [1 2 3 4]) ==> #{1 2 3 4}        "have a vector and want a set"
(into {} #{[1 2] [3 4]}) ==> {3 4, 1 2}    "have a set of vectors want a map"
(into #{} [{1 2} {3 4}]) ==> #{{1 2} {3 4}} "have a vector of maps want a set of maps"

intoconj컬렉션 유형에 따라 컬렉션에 새 항목을 적절하게 삽입하기위한 기본 추상화 인 래퍼 입니다. 그래서 친절이 흐름을 만드는 원리는 Clojure의이 빌드에 있다는 것이다 작성 가능 추상화 ,이 경우에는 into위에 conj수집의 상단에 seq.

위의 예는 수신자가 런타임에 전달되는 경우 여전히 잘 구성됩니다. 기본 추상화 ( seqconj)가 모든 컬렉션 (및 많은 Java 컬렉션에도 적용됨)에 대해 구현되므로 더 높은 추상화는 걱정할 필요가 없습니다. 많은 특수 데이터 관련 코너 케이스에 대해.


3
에 대한 +1 ... 비어 있지 않은 원래 컨테이너에서도 작동한다는 점에 주목할 가치가 있습니다 (예 : 컬렉션에 추가하려는 경우)
mikera

11
또한 주목할만한 가치가 있기 때문에 into사용이 conj,하고 (into '() some-seq)의 목록을 얻을 것 반대 때문에, 일부-서열의를 conjconses 목록에.
Chuck

into대부분의 다른 변환 수단보다 더 나은 성능 특성을 위해 (대부분의 seq 유형에 대해) 과도 현상 을 사용 한다는 점 은 주목할 가치가 있습니다.
Jarred Humphrey

그리고 이제는이 답변이 작성 될 당시 존재하지 않았던 트랜스 듀서와 함께 작동합니다. (과도 현상도 마찬가지인지 모르겠습니다) (이 답변은 유치원에 등록하기에 충분히 오래되었습니다)
Arthur Ulfeldt

33

vec, set그리고 일반적으로 into다른 컬렉션 유형으로 쉽게 "변환"할 수있는 친구입니다.

지도 벡터를지도지도로 어떻게 변환 하시겠습니까? 키가 필요합니다. 샘플 입력 / 예상 출력과 함께 사용할 수 있습니까?


죄송합니다.지도 세트를 의미했습니다. 지금 질문을 수정했습니다
appshare.co

22

벡터의 경우 vec기능이 있습니다.

user=> (vec '(1 2 3))
[1 2 3]

게으른 시퀀스의 경우 lazy-seq기능이 있습니다.

user=> (lazy-seq [1 2 3])
(1 2 3)

세트로 변환하는 set기능이 있습니다.

user=> (set [{:a :b, :c :d} {:a :b} {:a :b}])
#{{:a :b} {:a :b, :c :d}}

4
쓸데없는 간접적 인 지시를 추가하는 lazy-seq대신 지연되지 않은 호출이있을 때 seq. 정말로 당신이 비어 있지 않은 무언가를 반환하고 싶다면 sequence. lazy-seq다소 낮은 수준의 구조입니다.
cgrand

14

(완전성을 위해) 목록에서 맵으로 변환하는 것에 대한 또 하나의 답변- 여기에서 :

(apply hash-map '(1 2 3 4))
;=>{1 2, 3 4}

9

벡터를 목록으로 변환하려면 for다음과 같이 를 사용할 수도 있습니다 .

=> (for [i [1 2 3 4]] i)
(1 2 3 4)

데이터를 조작하지 않으려면 seq벡터에서 사용 하십시오.

=> (seq [1 2 3])
(1 2 3)

대신 for당신은 할 수(map identity [1 2 3 4])
siltalau

7

벡터를 목록 으로 변환 할 필요가 없습니다 . Clojure는 시퀀스가 ​​필요할 때 목록을 시퀀스로 처리하는 것처럼 벡터를 처리합니다. 예를 들면

user=> (cons 0 [1 2 3])
(0 1 2 3)

벡터가 시퀀스로 처리되고 있는지 확인해야하는 경우 다음으로 래핑합니다 seq.

user=> (conj [1 2 3] 0) ; treated as a vector
[1 2 3 0]

user=> (conj (seq [1 2 3]) 0) ; treated as a sequence
(0 1 2 3)

맵 벡터가 있고 맵 세트가 필요한 경우 벡터가 맵을 보유하고 있는지는 중요하지 않습니다. 평소와 같이 벡터를 세트로 변환하면됩니다.

user=> (set [{:a 1, :b 2} {"three" 3, "four" 4}])
#{{:a 1, :b 2} {"four" 4, "three" 3}}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.