Clojure 有反向映射功能吗?

Clojure 有反向映射功能吗?,clojure,Clojure,在clojure中,可以将函数映射到值序列。是否有内置函数将单个值作为参数映射到函数序列 (map inc [1 2 3 4]) ; -> (2 3 4 5) (reverse-map [inc dec str] 1) ; -> (2 0 "1") (reverse-map [str namespace name] :foo/bar/baz) ; -> (":foo/bar/baz" "foo/bar" "baz") 不确定是否有,但很容易实现: (def reverse

在clojure中,可以将函数映射到值序列。是否有内置函数将单个值作为参数映射到函数序列

(map inc [1 2 3 4])
; -> (2 3 4 5)

(reverse-map [inc dec str] 1)
; -> (2 0 "1")

(reverse-map [str namespace name] :foo/bar/baz)
; -> (":foo/bar/baz" "foo/bar" "baz")

不确定是否有,但很容易实现:

(def reverse-map (fn [l value] (map #(% value) l)))

有一个有点类似的
juxt
。它接受多个函数并返回一个函数,该函数将其参数传递给每个函数并返回返回值向量。因此:

> ((apply juxt [inc dec str]) 1)
[2 0 "1"]
主要区别在于它创建了一个向量,当然是渴望的(即不懒惰的)。原始的
map
创建了一个懒惰的序列

juxt
也适用于具有多个参数的函数:

> ((apply juxt [* / -]) 6 2)
[12 3 4]

如果懒惰不是必须的,我会说使用juxt,特别是因为它的写作能力。但是,使用map和repeat(两者都是惰性的)的polyadic函数的简单版本的反向映射如下所示:

(defn reverse-map
  [fcoll & args]
  (map apply fcoll (repeat args)))

=> (reverse-map [inc dec str] 1)
(2 0 "1")
=> (reverse-map [* / -] 6 2)
(12 3 4)
好吧,我想说一句,这是一个与juxt具有相同可组合性的版本。而且它甚至似乎是


虽然应用程序不是必需的,(juxt*/-)也可以。@NielsK你是对的,但我留下应用程序是为了展示如何按照询问者的要求使用它来“有趣地映射”函数序列。
(defn lazy-juxt
  [& funs]
  (fn [& args]
    (map apply funs (repeat args))))

=> ((juxt inc dec str) 1)
[2 0 "1"]
=> ((lazy-juxt inc dec str) 1)
(2 0 "1")

=> ((juxt * / -) 6 2)
[12 3 4]
=> ((lazy-juxt * / -) 6 2)
(12 3 4)