What is the best way to translate multidimensional cell array generation from Matlab to Clojure

I am halfway through figuring out a solution to my question, but I have a feeling that it will not be very effective. I have a 2-dimensional cell structure of variable length arrays which is constructed in Matlab in a very non-functional way that I would like to convert to Clojure. Here is an example of what I'm trying to do:

pre = cell(N,1);
aux = cell(N,1);
for i=1:Ne
  for j=1:D
    for k=1:length(delays{i,j})
        pre{post(i, delays{i, j}(k))}(end+1) = N*(delays{i, j}(k)-1)+i;
        aux{post(i, delays{i, j}(k))}(end+1) = N*(D-1-j)+i; % takes into account delay
    end;
  end;
end;

My current implementation plan is to use 3 cycles, where the first is initialized with a vector of N vectors of an empty vector. Each sublayer is initialized by the previous cycle. I define a separate function that takes a common vector and subindexes and a value and returns a vector with an updated sub-vector.

, 3 /recurs. , , .

+3
2

100%, , ( Matlab), :

(defn conj-in
  "Based on clojure.core/assoc-in, but with vectors instead of maps."
  [coll [k & ks] v]
  (if ks
    (assoc coll k (conj-in (get coll k []) ks v))
    (assoc coll k v)))

(defn foo []
  (let [w 5, h 4, d 3
        indices (for [i (range w)
                      j (range h)
                      k (range d)]
                  [i j k])]
    (reduce (fn [acc [i j k :as index]]
              (conj-in acc index
                       ;; do real work here
                       (str i j k)))
            [] indices)))

user> (pprint (foo))
[[["000" "001" "002"]
  ["010" "011" "012"]
  ["020" "021" "022"]
  ["030" "031" "032"]]
 [["100" "101" "102"]
  ["110" "111" "112"]
  ["120" "121" "122"]
  ["130" "131" "132"]]
 [["200" "201" "202"]
  ["210" "211" "212"]
  ["220" "221" "222"]
  ["230" "231" "232"]]
 [["300" "301" "302"]
  ["310" "311" "312"]
  ["320" "321" "322"]
  ["330" "331" "332"]]
 [["400" "401" "402"]
  ["410" "411" "412"]
  ["420" "421" "422"]
  ["430" "431" "432"]]]

, indices (), conj assoc -, --.

, make-array aset. Clojure Java; , . Clojure , , .

( , .)

(defn bar []
  (let [w 5, h 4, d 3
        arr (make-array String w h d)]
    (doseq [i (range w)
            j (range h)
            k (range d)]
      (aset arr i j k (str i j k)))
    (vec (map #(vec (map vec %)) arr))))  ;yikes?
+2
+1

Source: https://habr.com/ru/post/1767212/


All Articles