Подтвердить что ты не робот

Как реализовать цикл For в Clojure

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

struct mystruct {
   int id;
   int price;
};

mystruct mydata[10];

for (int i=0; i<10; i++) {
  myfunction(mydata[i].id, mydata[i].price);
  //other things...
}

Я начинаю с Clojure, и мне очень сложно сделать что-то простое, но я действительно стараюсь учиться как можно больше, поскольку я знаю, что есть большие преимущества с Clojure, например, использование рефов...

Я был бы очень признателен, если бы кто-нибудь мог мне помочь. Спасибо!!

4b9b3361

Ответ 1

Одним из способов перевода императива для цикла в Clojure является использование макроса for.

(for [i (range 10)] (inc i))

Вышеуказанная функция вернет все числа от 0 до 9 с шагом 1. Однако, похоже, вы просто хотите перебирать последовательную коллекцию и использовать каждый элемент. Если это все, что вам нужно, то вам не нужно ссылаться на значение индекса, вместо этого вы можете напрямую ссылаться на каждый элемент.

(for [d my-vec-of-data] (my-function d))

Однако для этого простого случая функция map, вероятно, будет лучшим выбором, потому что она предназначена для вызова функций с аргументами из коллекций. Следующий пример эквивалентен использованию for выше.

(map my-function my-vec-of-data)

Оба map и for возвращают коллекцию значений, состоящую из значений, возвращаемых my-function. Это связано с тем, что структуры данных Clojure неизменяемы, поэтому необходимо вернуть новую коллекцию. Если это не то, что вам нужно, или если ваша функция имеет побочные эффекты, вы можете использовать doseq вместо for, который возвращает nil.

Ответ 2

Ответ Джереми хорош для того, как сделать цикл for в идиоматическом Clojure.

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

(defmacro for-loop [[sym init check change :as params] & steps]
 `(loop [~sym ~init value# nil]
    (if ~check
      (let [new-value# (do [email protected])]
        (recur ~change new-value#))
      value#)))

Использование следующим образом:

(for-loop [i 0 (< i 10) (inc i)] 
  (println i))