0

I am looking for a way to check if a current value in a collection is greater than the next value, and if so, add that pair of items to a collection eg:

[9 2 3 7 11 8 3 7 1] => [9 2 11 8 8 3 7 1] ; Checking each item against the next

I initially thought I could do something like:

(filter (fn [[x y]] (> x y)) [9 2 3 7 11 8 3 7 1]) 

But something like this seemed to work only with associative types. So then I tried something like this:

(defn get-next [col index] ; Returns next item from a collection
  (get col (inc (.indexOf col index))))

(filter (fn [[x]] (> x (get-next [9 2 3 7 11 8 3 7 1] x))) [9 2 3 7 11 8 3 7 1]) 

But still I got the same error. Any help would be appreciated

kazuwal
  • 1,071
  • 17
  • 25

2 Answers2

3

Use partition function to make pair of current and next item in a collection.

user=> (partition 2 1 [9 2 3 7 11 8 3 7 1])
((9 2) (2 3) (3 7) (7 11) (11 8) (8 3) (3 7) (7 1))

Now you have pair of current and next item in the collection. you can compare the items in each pair and concat the result with mapcat.

user=> (->> [9 2 3 7 11 8 3 7 1]
  #_=>      (partition 2 1)
  #_=>      (mapcat (fn [[a b]] (if (> a b) [a b]))))
(9 2 11 8 8 3 7 1)
ntalbs
  • 28,700
  • 8
  • 66
  • 83
0

Another way is to use reduce:

(defn pairs [data]
  ((reduce (fn [res item]
             (if (and (:prev res) (< item (:prev res)))
               (assoc res
                      :prev item
                      :res (conj (:res res) (:prev res) item))
               (assoc res :prev item)))
           {:prev nil :res []} data) :res))

(pairs [9 2 3 7 11 8 3 7 1])
;; [9 2 11 8 8 3 7 1]