2011-04-29 3 views
4

나는 Clojure에서 띄엄 띄엄 채워진 다차원 벡터를 만들려고 노력하고있다. 그러나 나는 지식의 한계에 다가 가고있다.클로저에 드문 드문 채워진 다차원 벡터?

컬렉션이 있습니다. x 저는 반복 작업 중이며 크기가 (count x)(count x) 인 다차원 벡터를 만들고 싶습니다. 대부분의 셀은 비어 있지만 x 축과 y 축이 일치하는 지점 (예 : (1 1), (2 2), (3 3) 등)에서 함수를 실행하여 if 그 공간에 값을 넣어야합니다. 절차 언어에서

, 그것은 것 같은 뭔가 :

for (i = 0; i < length(x); i++) { 
    for (j = 0; j < length(x); j++) { 
     if (i == j && testReturnsTrue(x[i])) { 
      table[i][j] = (list x[i]) 
     } 
     else { 
      table[i][j] =() 
     } 
    } 
} 

하지만이이 Clojure의에서 할 수 얼마나 주위에 내 머리를 정리하고 수 없습니다. 나는 내포와 중첩 된 루프 - 반복 구조를 위해 중첩을 사용하여 시도했지만 어느 쪽도 작동하지 못한다.

또는 올바른 크기의 변경 가능한 테이블을 만들고 빈 목록으로 모두 초기화 한 다음 x의 각 요소를 확인하면서 값을 설정할 수 있지만 가능하면 테이블을 불변으로 유지하고 싶습니다.

+0

FWIW "희소"라는 단어는 답장 된 모든 사람들을 혼란스럽게 만들었습니다. 당신의 벡터가 나중에 채워지고 단지 희박한 * now * 일 경우, 희박 지향 기술은별로 의미가 없습니다. 나는 당신이 질문을 변경하거나 명확하게 제안한다. – amalloy

답변

4

중첩 for의 내가 어떻게 할 것입니다 :

(def x [:a :b :c :d]) 
(vec (for [i (range (count x))] 
     (vec (for [j (range (count x))] 
       (if (and (= i j) (identity (x i))) 
       [(x i)] 
       []))))) 
=> [[[:a] [] [] []] [[] [:b] [] []] [[] [] [:c] []] [[] [] [] [:d]]] 

(identity (x i)) 독립에 테스트의 일종입니다.

편집 : 다른 답변에서 언급했듯이이 구조체가 드문 드문 채로 남아있는 경우 해시지도를 사용하는 것이 더 좋습니다. 나중의 계산에서 빈 부분을 채울 것으로 가정하고있었습니다.

+0

훌륭합니다, 감사합니다! 나는 테이블의 나머지 부분을 채울 것이고, 이것은 대각선에 데이터를 놓는 첫 번째 패스 일뿐입니다. – stomcavage

+0

나머지를 채우더라도 해시 맵은 숫자 순서대로 키를 반복하지 않는 한 적어도 좋은 것입니다. 모두 무작위 접근이라면 해시 맵이 더 명확하다고 생각합니다. – amalloy

11

해시 맵을 사용 하시겠습니까? 희소 할 수없는 벡터는 필요 없습니다. 또한이 필수 솔루션은 희소성이없는 것처럼 보입니다. 즉, 많은 수의 빈 셀을 저장하는 메모리를 낭비하고 있습니다. 아마도 다음과 같은 것일 수 있습니다.

(let [indexed (map-indexed vector xs)] 
    (reduce (fn [m [i x]] 
      (if (test? x) 
       (assoc-in m [i i] x) 
       m)) 
      {} 
      indexed)) 
관련 문제