A neat way to apply a function to every nth element of a sequence?

What a neat way to map a function to every nth element in a sequence? Something like (map-every-nth fn coll n) , so that it will return the original sequence with only the conversion of every nth element, for example. (map-every-nth inc (range 16) 4) will return (0 1 2 4 4 5 6 8 8 9 10 12 12 13 14 16)

+6
source share
3 answers

Try the following:

 (defn map-every-nth [f coll n] (map-indexed #(if (zero? (mod (inc %1) n)) (f %2) %2) coll)) (map-every-nth inc (range 16) 4) > (0 1 2 4 4 5 6 8 8 9 10 12 12 13 14 16) 
+10
source

I suggest that this be simpler and cleaner than the accepted answer:

 (defn map-every-nth [f coll n] (map f (take-nth n coll))) 

This is good to know: http://clojuredocs.org/clojure_core/clojure.core/take-nth

+2
source

I personally like this solution better:

 (defn apply-to-last [f col] (concat (butlast col) (list (f (last col))))) (apply concat (map #(apply-to-last (fn [x] (* 2 x)) %) (partition 4 (range 16)))) 

Or as a function:

 (defn apply-to-last [f col] (concat (butlast col) (list (f (last col))))) (defn map-every-nth [f col n] (apply concat (map #(apply-to-last f %) (partition n col)))) (map-every-nth (fn [x] (* 2 (inc x))) (range 16) 4) ; output: (0 1 2 8 4 5 6 16 8 9 10 24 12 13 14 32) 

Please note that this easily leads to the possibility of apply-to-first , apply-to-second or apply-to-third , which makes it possible to control the "beginning" of the display of each nth element.

I do not know the performance of the code that I wrote above, but for me it looks more idiomatic.

0
source

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


All Articles