blackened
blackened

Reputation: 903

Clojure: Increment every item of a list/vector by its first element

My try:

(defn inc-by-f [v]
      map #(+ (first v) %) v)

EDIT

(The original question was stupid; I missed the parenthesis. I am still leaving the question, so that perhaps I learn some new ways to deal with it.)

(defn inc-by-f [v]
  (map #(+ (first v) %) v))

What other cool “Clojure” ways to achieve the desired result?

Upvotes: 0

Views: 699

Answers (2)

tar
tar

Reputation: 1568

"Cooler" way (answered later than https://stackoverflow.com/a/62536870/823470 by Bob Jarvis):

(defn inc-by-f
  [[v1 :as v]]
  (map (partial + v1) v))

This uses

Note that the vector destructuring is only useful if the increment value is in a place that is easily accessible by destructuring. It could work if the value was the "2nd in the vector" ([_ v2 :as v]), for example, but not if the value was "the maximum element in the vector". In that case, the max would have to be obtained explicitly, e.g.

(defn inc-by-max
  [v]
  (map (partial + (apply max v)) v))

Also note that anonymous functions are evaluated on each call, unlike partial which is handed all its arguments and then those no longer need to be evaluated. In other words, if we take the first element of a 1000-element v inside the anonymous function, that will result in 1000 calls to first, instead of just one if we get the first element and pass it to partial. Demonstration:

user=> (dorun (map #(+ (do (println "called") 42) %) (range 3)))
called
called
called
=> nil
user=> (dorun (map (partial + (do (println "called") 42)) (range 3)))
called
=> nil

Upvotes: 5

You're missing parentheses around the map invocation. The following works as you expect:

(defn inc-by-f [v]
  (map #(+ (first v) %) v))

Upvotes: 3

Related Questions