2016-06-19 6 views
0

Clojure에서 recur를 사용하지 않고 신속하게 요소에 여러 번 assoc을 적용 할 수 있습니까? 이다Clojure에서 루프를 사용하여 여러 번 assoc 적용

, 같은 : 코드 위

(defn set-thing 
    [foo i val] 
    (assoc foo i val)) 

(let [foo [3 4 2 5 8]] 
    (last (for [i (range 0 (count test))] 
    (set-thing foo i 32))) 

그러나 분명히 난 후 나는 무엇을하지 않습니다. 위의 함수는 마지막 값이 32이고 나머지는 변경되지 않은 벡터를 반환합니다. 내가하는 일은 모든 값이 32로 설정된 벡터를 다시 얻는 것입니다.

위 코드의 코드와 코드가 크게 다르기 때문에 set 함수를 사용하는 것이 절대적으로 필요합니다. 지도의 사용. 실제 코드는 구조체의 구조체에 꽤 깊숙이 들어가 있습니다.

재발을 사용하지 않고이 효과를 다시 얻을 수 있습니까?

편집 : 여기

코드의 조각 내가 달성하고자하는 일을, 루프를 사용하고 재발입니다. 다큐 멘 테이션 코멘트의 "터미널"나는 그 작업입니다 라이브러리를 참조한다

(defn fill! 
    "Fills the terminal with one specific tile." 
    [{:keys [screen] :as term} tex-x tex-y color] 
    (let [grid-width (screen :grid-width) 
     grid-height (screen :grid-height)] 
    (loop [x 0 
      y 0 
      term term] 
     (if (= x grid-width) 
     (if (= y grid-height) 
      term 
      (recur 0 (inc y) ((term :set-char!) term x y tex-x tex-y color))) 
     (recur (inc x) y ((term :set-char!) term x y tex-x tex-y color)))))) 

은 응용 프로그램 개발에 사용할 수있는 터미널을 시뮬레이션 할 예정이다. 당신이 값 32 5 개 인스턴스의 순서가 필요한 경우

+1

'set' 함수의 목적은 무엇입니까? 그것은 ['clojure.core/set'] (http://clojuredocs.org/clojure.core/set)에 그림자를 드리 우며''assoc' (http://clojuredocs.org/)의 덜 유용한 버전 인 것처럼 보입니다. clojure.core/assoc). –

+0

내가 가지고있는 코드는 훨씬 더 고급이며, 그 안에는 set 함수의 이름이 실제로 설정되어 있지 않습니다. 오히려 타일 세트 (x, y, tex-x, tex-y 및 색상 매개 변수를 사용하여)의 격자에 하나의 타일을 설정하고 응용 프로그램의 현재 상태를 반환하는 기능이 있습니다. 그래서, 제가하려고하는 것은 x와 y 좌표의 전체 그리드에 걸쳐 모든 타일을 같은 타일 유형으로 반복하는 것입니다. 따라서 set 메소드가 필요합니다. –

답변

1

내가도의 당신이이 용어 정의가 있다고 가정 해 보자

(그리드 값을 설정)하여 업데이트를 위해 당신에게 변형을 제안 할 것, (완전히 올바른 사람이되는) reduce를 사용하도록 조언합니다 :

(def term {:screen {:grid-width 5 
        :grid-height 3} 
      :set-char! (fn [term & other] 
         (println :setting other) 
         term)}) 
우선

당신이 (용어 업데이트에 대한) reduce의 조합으로 loop/recur을 대체 할 수 및 for 지능형리스트 ((for [x (range 2) y (range-3)] [x y])는 쌍의 좌표 모든 생성 들) REPL에서

(defn fill! 
    [{{:keys [grid-width grid-height]} :screen 
    set-char! :set-char!} 
    tex-x tex-y color] 
    (reduce (fn [term [x y]] (set-char! term x y tex-x tex-y color)) 
      term 
      (for [x (range grid-width) 
       y (range grid-height)] 
      [x y]))) 

:

user> (fill! term 101 102 103) 
:setting (0 0 101 102 103) 
:setting (0 1 101 102 103) 
:setting (0 2 101 102 103) 
:setting (1 0 101 102 103) 
:setting (1 1 101 102 103) 
:setting (1 2 101 102 103) 
:setting (2 0 101 102 103) 
:setting (2 1 101 102 103) 
:setting (2 2 101 102 103) 
:setting (3 0 101 102 103) 
:setting (3 1 101 102 103) 
:setting (3 2 101 102 103) 
:setting (4 0 101 102 103) 
:setting (4 1 101 102 103) 
:setting (4 2 101 102 103) 

{:screen {:grid-width 5, :grid-height 3}, :set-char! #function[user/fn--19918]} 

확인. 그것은 작동하지만, 당신의 세트 숯만큼! 함수가 부작용 (내 경우 문자열을 인쇄하고 화면을 업데이트하는 데 사용됨) 인 경우이 정확한 경우 (do[run|seq|all])로 설계된 clojure의 함수를 사용하여 줄일 필요없이 사용할 수 있습니다. doseq :

(defn fill2! 
    [{{:keys [grid-width grid-height]} :screen set-char! :set-char!} 
    tex-x tex-y color] 
    (doseq [x (range grid-width) y (range grid-height)] 
    (set-char! term x y tex-x tex-y color)) 
    term) 

이는 첫 번째 변형과 완전히 동일합니다.

3

당신은 reduce

(let [foo [3 4 2 5 8]] 
    (reduce (fn [acc k] 
      (set acc k 32)) 
      foo 
      (range (count foo)))) 
1

을 사용할 수 repeat 사용 : 당신은 벡터로 결과를해야하는 경우, vec를 사용

(repeat 5 32) 
;=> (32 32 32 32 32) 

:

(vec (repeat 5 32)) 
;=> [32 32 32 32 32] 

기존 컬렉션과 같은 크기로 결과를 필요 count 사용 : 당신이 원하는 경우

(vec (repeat (count [3 4 2 5 8]) 32)) 
;=> [32 32 32 32 32] 

당신은 함수로 이것을 패키지 수 :

(defn fill [v x] 
    (vec (repeat (count v) x))) 

(fill [3 4 2 5 8] 32) 
;=> [32 32 32 32 32] 
0

이 Clojure의 핵심 set을 재정의한다 아마 그런 좋은 생각이야. 여기서는 필요하지 않은 것 같기 때문에 아래 예제에서 직접 assoc을 사용했습니다.

constantly을 사용하여 원하는 횟수만큼 기능을 실행할 수 있습니다. 이 목록을 반환, 그래서 vec에 여분의 전화는 원하는 데이터 형식 얻을 수 있습니다 : 여기

user.core=> (let [foo [3 4 2 5 8]] 
     #_=> (vec (map (constantly 32) foo))) 
[32 32 32 32 32] 

내가 조금 청소기를 찾는 독자 매크로를 사용 @의 SERCE의 대답에 변화가입니다.또한

user.core=> (let [foo [3 4 2 5 8]] 
     #_=> (reduce #(assoc %1 %2 32) foo (range (count foo)))) 
[32 32 32 32 32] 
관련 문제