Clojure: Вызовите функцию для каждого элемента в векторе с ним индекс

В зависимости от Вашей проблемы GCCXML мог бы быть Вашим ответом. В основном это анализирует источник с помощью GCC и затем дает Вам легко удобоваримый XML дерева синтаксического анализа. С GCCXML Вы сделаны раз и навсегда.

26
задан Jeroen Dirks 30 October 2009 в 17:51
поделиться

4 ответа

То, как вы это делаете, идиоматично (и фактически идентично clojure.contrib.seq-utils / indexed ). Если вы действительно хотите избежать лишней структуры данных, вы можете сделать следующее:

(loop [data data, index 0]
  (when (seq data)
    (setCell 0 index (first data))
    (recur (rest data) (inc index))))

Я бы использовал вашу версию, если только не было веской причины этого не делать.

10
ответ дан 28 November 2019 в 06:24
поделиться

Лучшим способом было бы использовать clojure.contrib.seq-utils / indexed , который будет выглядеть так (с использованием деструктуризации):

(doseq [[idx val] (indexed ["Hello" "World" "Test" "This"])]
  (setCell 0 idx val))
8
ответ дан 28 November 2019 в 06:24
поделиться

Я провел краткое сравнение производительности параметров sofar:

; just some function that sums stuff 
(defn testThis
  [i value]
 (def total (+ total i value)))

; our test dataset. Make it non-lazy with doall    
(def testD (doall (range 100000)))

; time using Arthur's suggestion
(def total 0.0)
(time (doall (map #(testThis %1 %2) (iterate inc 0) testD)))
(println "Total: " total)

; time using Brian's recursive version
(def total 0.0)
(time (loop [d testD i 0]
  (when (seq d)
    (testThis i (first d))
    (recur (rest d) (inc i)))))
(println "Total: " total)

; with the idiomatic indexed version
(def total 0.0)
(time (let [idv (map vector (iterate inc 0) testD)]
  (doseq [[i value] idv] (testThis i value))))
(println "Total: " total)

Результаты на моем одноядерном ноутбуке:

   "Elapsed time: 598.224635 msecs"
   Total:  9.9999E9
   "Elapsed time: 241.573161 msecs"
   Total:  9.9999E9
   "Elapsed time: 959.050662 msecs"
   Total:  9.9999E9

Предварительный вывод:

Используйте решение «цикл / повтор».

1
ответ дан 28 November 2019 в 06:24
поделиться

Вы можете получить тот же эффект очень идиоматическим способом, просто сопоставив индексы с данными.

(map #(setCell 0 %1 %2) (iterate inc 0) data)

Вы можете заключить это в (doall или (dosq , чтобы вызовы происходили сейчас. Это нормально - сопоставить бесконечную последовательность с конечной, потому что отображение остановится, когда истечет самая короткая последовательность.

27
ответ дан 28 November 2019 в 06:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: