2
votes

In Clojure, I want to both rename-keys and select-keys from a map. The simple way of doing is with:

(-> m
    (rename-keys new-names)
    (select-keys (vals new-names)))

But this will itetate over the entire map twice. Is there a way to do it with one iteration?

1
if your new-names is quite small but m is large, you could just select first over (**keys** new-names) and then rename the (small) resultcfrick
If you don't need the result to be a map but just a function you can also do it with no iteration: (comp m new-names-to-old-names-map)cgrand
Why wouldn't you do somethnig like this? {:new-key-1 (my-map :old-key-1) :new-key-2 (my-map :old-key-2) :new-key-3 (my-map :old-key-3)}WarFox

1 Answers

9
votes

Sure, there is a way to do it with a single iteration.

You could do it using reduce-kv function:

(reduce-kv #(assoc %1 %3 (get m %2)) {} new-names)

or just a for loop:

(into {} (for [[k v] new-names] [v (get m k)]))

If you want a really simple piece of code, you could use fmap function from algo.generic library:

(fmap m (map-invert new-names))