2012-11-02 4 views
2

assoc-in은 벡터/맵에서 색인/키의 값을 변경할 수 있습니다. 지도에서 키가 존재하지 않으면 새로운 키/값 쌍을 만듭니다. 위의 코드새지도 대신 새로운 벡터를 만들 수 있습니까?

(reduce (fn [g [x y]] (assoc-in g [x y] y)) 
     [] 
     (for [x (range 2) 
       y (range 2)] 
      [x y])) 

생성 : I가 원하는

[{1 1, 0 0} {1 1, 0 0}] 

같은 벡터의 비슷한 뭔가 (인덱스가 존재하지 않는 경우, 그것은 그 인덱스에 그 값 목록을 만드는) 것이 있습니다 생성 :

[[0 1] [0 1]] 

간단한 방법으로 가능합니까?

감사

편집 : 내가 그냥 지금은 값으로 Y를 넣어하지만 그냥 예입니다 대신 중첩 된지도 (또는지도의 벡터)의 중첩 된 벡터를 생성 할, 더 명확합니다.

+0

[[0 1] [0 1]] '이 무엇을 의미하는지 명확히 할 수 있습니까? '(범위 2) '에서 생성 된 두 벡터의 벡터입니까? 또는 다른 것? –

+0

물론 미안하지만. 난 그냥 중첩 된지도 (또는 벡터의 벡터) 중첩 된 벡터를 생성하려면 내 질문을 편집 할거야 – user1782011

답변

6

을하기 때문에 할 수있는 유일한 assoc 기존 인덱스 또는 벡터의 다음 인덱스 당신 :

user=> (assoc [:a] 0 :b) ; works because index 0 exists 
[:b] 
user=> (assoc [:a] 1 :b) ; works because index 1 is next 
[:a :b] 
user=> (assoc [:a] 2 :b) ; fails since index is out of range 
IndexOutOfBoundsException clojure.lang.PersistentVector.assocN (PersistentVector.java:136) 

그러나주의를 기울이면 여전히 효과적 일 수 있습니다. 여기 assoc-in의 구현은 다음과 같습니다가 if 조건의 진정한 분기에 get 호출

(defn assoc-in 
    [m [k & ks] v] 
    (if ks 
    (assoc m k (assoc-in (get m k) ks v)) 
    (assoc m k v))) 

공지있다. 대신 벡터를 사용 assoc-in의 자신의 버전을 원한다면, 당신은 get에 의해 반환되는 기본값으로 빈 벡터를 추가 할 수 있습니다

(defn vassoc-in 
    [m [k & ks] v] 
    (if ks 
    (assoc m k (vassoc-in (get m k []) ks v)) 
    (assoc m k v))) 

[[0 1] [0 1]]에 질문 결과에 샘플 코드에 vassoc-in보다는 assoc-in을 사용하여 단지 네가 원했던 것처럼.

+0

네, 이것이 제가 원했던 것입니다. 설명 해줘서 고마워. – user1782011

+0

@ user1782011 - 듣기 좋다! 이것이 당신이 찾고있는 것이라면, 당신은 나의 대답을 받아 들일 수 있습니다. – DaoWen

+1

늦게까지 한 번 해보지 마세요 :) 미안해. – user1782011

0

당신이 같은 필요 보인다 : 일반적인 경우에서 잘 작동하지 않습니다 맵이 아닌 벡터를 만들기

user=> (let [cv #(apply vector %)] 
     (cv (map cv (repeat 5 (range 2))))) 
[[0 1] [0 1] [0 1] [0 1] [0 1]] 
+1

'# (벡터 % 적용)'그냥 'vec'. – amalloy

관련 문제