2015-12-22 5 views
1

в Clojure Я использую следующую функцию для инициализации 2d вектора:Clojure: инициализировать 2d вектор

(defn vec2d [x y init] 
    (vec (map 
     #(vec (map init (range x))) (range y)))) 

использование:

(def grid (vec2d 40 30 (fn [] "x"))) 

Так как я новичок в языке, я спрашиваю если это самый прямой способ сделать это. У кого-нибудь есть идея оптимизировать это?

+0

Это довольно запутанным. Что вы пытаетесь вставить, и что вы хотите выбраться? – jmargolisvt

+0

Извините, в коде что-то не так. теперь он обновлен. –

+0

Если вы много работаете с 2D-структурами, вы можете рассмотреть core.matrix. – Mars

ответ

3

В предположении, что вы всегда будете хотеть, чтобы инициализировать элементы вектора постоянной, вот как я бы это сделать:

(defn vec2d 
    "Return an x by y vector with all entries equal to val." 
    [x y val] 
    (vec (repeat y (vec (repeat x val))))) 
2

, если вы хотите, чтобы иметь возможность инициализировать в соответствии с координат, вы могли бы сделать это

(defn vec2d [sx sy f] 
    (mapv (fn[x](mapv (fn[y] (f x y)) (range sx))) (range sy))) 

Это позволяет иметь постоянное значение, если вы

(vec2d 4 3 (constantly 2)) 
;; [[2 2 2 2] [2 2 2 2] [2 2 2 2]] 

или инициализировать в соответствии с координатами, скажем:

(vec2d 4 3 (fn[x y] (+ x y))) 
(vec2d 4 3 +)       ;; or more concisely 
;;[[0 1 2 3] [1 2 3 4] [2 3 4 5]] 
1

Используйте mapv и вы установите

(defn vec2d [x y init] 
    (mapv #(mapv init (range x)) (range y))) 

Если вы хотите, координаты для инициализации:

(defn vec2d [x y init] 
    (mapv (fn [y] (mapv #(init % y) (range x))) (range y)) 

вложенную для это также очень читаемо для создания плат, если вы просто хотите, чтобы все ячейки:

(defn vec2d [cols rows init] 
    (for [x (range rows) y (range cols)] 
    (init x y))) 

Или, если вы не возражаете seqs:

(defn vec2d [cols rows init] 
    (for [x (range rows)] 
    (for [y (range cols)] 
     (init x y)))) 
Смежные вопросы