Question

I'm trying to write a more general map function for Clojure, but am unable to map a function over a nested vector. In particular the the map should admit a parameter n, which allows level specification of the nesting.

Here's what I've written so far, which fails with nested vectors:

(defn cloj-maps 
([f x]     (vec (map f x)))
([f x y]   (vec (map f x y)))
([f x y z] (vec (map f x y z))))

Here is a sample of what I am trying to input/output:

Input 1: (inc [[1 2] [3 4]] 1) where inc is input function, [[...]] is nested vector, and 1 is level specification.

Output1: [[2 3] [4 5]]

Symbolically [f[a b] f[c d]] which is mapping at the top level.

Input 2: (inc [[1 2] [3 4]] 2)

Output 2: [[3 4] [5 6]]

Symbolically [f[f[a] f[b]] f[f[c] f[d]]] where I have used f for function, and replaced {1,2,3,4}->{a,b,c,d}. Here the input parameter 2 implies mapping at levels 1 and 2, hence f "wrapped" around each element and each vector.

Was it helpful?

Solution

I don't understand why you would want to do this, but this might do what you're looking for:

(defn cloj-maps [f n x]
  (let [f' (nth (iterate #(comp f %) identity) n)]
    ((fn deep [y]
        (if (vector? y)
          (mapv deep y)
          (f' y)))
       x)))

Sample outputs:

user=> (cloj-maps inc 0 [[1 2] [3 4]])
[[1 2] [3 4]]
user=> (cloj-maps inc 1 [[1 2] [3 4]])
[[2 3] [4 5]]
user=> (cloj-maps inc 2 [[1 2] [3 4]])
[[3 4] [5 6]]
user=> (cloj-maps inc 3 [[1 2] [3 4]])
[[4 5] [6 7]]
user=> (cloj-maps inc 4 [[1 2] [3 4]])
[[5 6] [7 8]]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top