Search code examples
clojure

Map only selected elements in a list


Suppose I have a list of elements L, a function g, and a list of indices I.

Then, how can I map the function g only to the elements of the list L specified by the indices I?

For instance, if g is the squaring function, L is the list (1 2 3 4 5 6 7) and I is the set of indices (1 3 4), then I should obtain (1 4 3 16 25 6 7), that is the list L in which I squared the elements in positions I.

(The first index is 0, like it is used in the nth function)

I can do it in some way or another, but I was wondering if there is a simple way to do it.


Solution

  • Or, without a library, you can just make use of map-indexed:

    (def I #{1 3 4})
    (def L '(1 2 3 4 5 6 7))
    
    (defn g [n] (* n n))
    
    
    (map-indexed #(if (I %) (g %2) %2) L))
    
    ; or, with explicit parameters
    
    (map-indexed (fn [i n] (if (I i) (g n) n)) L)
    
    ; Both produce a lazy-list of (1 4 3 16 25 6 7)
    

    Of course, with better names, this would be a lot more readable.

    I have I as a set here instead of a list so lookups can be done efficiently. If you have it as a list originally, you can convert it to a set using set.

    Also note, this produces a lazy-list. If you want a different structure, you can use vec for example to force it into a vector afterward.