Как мне работать с каждым элементом в векторе И ссылаться на предыдущее значение в Clojure? - PullRequest
4 голосов
/ 02 марта 2010

Дано:

(def my-vec [{:a "foo" :b 10} {:a "bar" :b 13} {:a "baz" :b 7}])

Как можно перебрать каждый элемент для вывода этого элемента: a и суммы всех: b для этой точки? То есть:

"foo" 10
"бар" 23
"Баз" 30

Я пытаюсь такие вещи безрезультатно:

; Does not work!    
(map #(prn (:a %2) %1) (iterate #(+ (:b %2) %1) 0)) my-vec) 

Это не работает, потому что "iterate" lazy-seq не может ссылаться на текущий элемент в my-vec (насколько я могу судить).

ТИА! Шон

Ответы [ 3 ]

6 голосов
/ 02 марта 2010
user> (reduce (fn [total {:keys [a b]}]
                  (let [total (+ total b)]
                    (prn a total)
                    total))
              0 my-vec)
"foo" 10
"bar" 23
"baz" 30
30
1 голос
/ 02 марта 2010

Это можно рассматривать как начало с последовательности карт, отфильтровывая последовательность значений: a и отдельную последовательность скользящей суммы значений: b, а затем отображая функцию двух аргументов на два производных последовательности.

создать последовательность только значений: a и: b с помощью

(map :a my-vec)
(map :b my-vec)

затем функция для получения скользящей суммы:

 (defn sums [sum seq]
   "produce a seq of the rolling sum"
   (if (empty? seq) 
      sum
      (lazy-seq
        (cons sum
              (recur (+ sum (first seq)) (rest seq))))))

затем сложите их вместе:

(map #(prn %1 %s) (map :a my-vec) (sums 0 (map :b my-vec))) 

Этот отделяет проблему генерации данных от обработки . Надеюсь, это облегчит жизнь.

PS: какой лучший способ получить скользящую сумму?

0 голосов
/ 02 марта 2010

Преобразуйте его в суммированную последовательность:

(defn f [start mapvec]
   (if (empty? mapvec) '()
       (let [[ m & tail ] mapvec]
          (cons [(m :a)(+ start (m :b))] (f (+ start (m :b)) tail)))))

Вызывается как:

(f 0 my-vec)

возвращается:

(["foo" 10] ["bar" 23] ["baz" 30])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...