1
votes

Given a function, vectors or arrays, and level specification as input. What is the simplest way in Clojure to output pairwise threading of the function? Given two vectors I first tried

(vec (interleave [:a :b] [1 2]))
[:a 1 :b 2]

For arrays I used

(vec (map interleave [[:a :b] [:c :d]] [[1 2] [3 4]]))
[(:a 1 :b 2) (:c 3 :d 4)]

which doesn't exactly output an array. Is this the right way to go for pairwise threading of a function?

Here's a sample of what I am trying to do

Input 1: [+ [[1 2] [3 4]] [[1 2] [3 4]] 2]

Output 1: [[2 4] [6 8]]

Input 2: [+ [1 2 3 4] [1 2 3 4]]

Output2: [2 4 6 8]

1
That is not what a clojure array is. In clojure an array is a mutable java object of fixed length, and you usually don't need them. What you are specifying is a nested vector.noisesmith

1 Answers

2
votes

To specify the depth of recursion as a numeric argument seems odd, for the same reason to usage of flatten is suspicious: it can be a workaround for the fact that you don't sufficiently understand or properly specify the algorithm creating the structure you are operating on.

For starters, to map over subsequences, you can use nested calls to map.

Also if you want map to create a vector (and be eager, which is a side effect of vector creation), you can use mapv.

(mapv (partial mapv +) [[1 2] [3 4]] [[1 2] [3 4]])

now to attempt to use a numeric argument for the depth of mapv recursion:

user> 
(defn mapdepth-rec
  [depth f & args]
  (if (= depth 1)
    (apply mapv f args)
    (apply mapv (partial mapdepth-rec (dec depth) f) args)))

#'user/mapdepth-rec
user> 
(defn mapdepth [f a b & [depth]] (let [depth (or depth 1)] (mapdepth-rec depth f a b)))

#'user/mapdepth
user> (mapdepth + [[1 2] [3 4]] [[1 2] [3 4]] 2)
[[2 4] [6 8]]
user> (mapdepth + [1 2 3 4] [1 2 3 4])
[2 4 6 8]