如果我想在矢量重复的Clojure中构建一个表,我会写:
(take 2 (repeat [1 2 3]))
但是我如何扩展这个表函数的概念来构建类似的东西:
输入1:[a ^ 2 2 6 2]其中a ^ 2是某个输入函数,2是最小值,6是最大值,2是步长。
输出1:[4,16,36]
输入2:[b ^ 2 10 -5 -2]
输出2:[100 64 36 16 4 0 4 16]
输出4x3矩阵
输入3:[(+(* 10 i)j)[1 4] [1 3]]
其中(+(* 10 i)j)是10i + j(某些给定的输入函数),[1 4]是i的最小值和最大值,[1 3]是j的最小值和最大值。
产出3:[[11 12 13] [21 22 23] [31 32 33] [41 42 43]]
答案 0 :(得分:1)
您希望以嵌套方式使用for
:
(for [i (range 1 (inc 4))]
(for [j (range 1 (inc 3))]
(+ (* 10 i) j)))
;; '((11 12 13) (21 22 23) (31 32 33) (41 42 43))
编辑扩展了一个示例实现
例如:
(defn build-seq [f lower upper step]
(for [i (range lower (+ upper step) step)]
(f i)))
(build-seq #(* % %) 2 6 2)
;; '(4 16 36)
(defn build-table [f [ilower iupper] [jlower jupper]]
(for [i (range ilower (inc iupper))]
(for [j (range jlower (inc jupper))]
(f i j))))
(build-table #(+ (* 10 %) %2) [1 4] [1 3])
;; '((11 12 13) (21 22 23) (31 32 33) (41 42 43))
您的三个输入/输出样本不会为一个变量和两个变量显示一致的签名;此外,step
参数似乎是可选的。我对保留样本语法的漂亮API的存在持怀疑态度,但我可以尝试不同的东西(即使我确实认为简单的嵌入式for
形式是更好的解决方案):
(defn flexible-range [{:keys [lower upper step] :or {lower 0}}]
(let [[upper step] (cond
(and upper step) [(+ upper step) step]
step (if (pos? step)
[Double/POSITIVE_INFINITY step]
[Double/NEGATIVE-INFINITY step])
upper (if (< lower upper)
[(inc upper) 1]
[(dec upper) -1])
:else [Double/POSITIVE_INFINITY 1])]
(range lower upper step)))
(defn build-table
([f [& params]]
(for [i (flexible-range params)]
(f i)))
([f [& iparams] [& jparams]]
(for [i (flexible-range iparams)]
(for [j (flexible-range jparams)]
(f i j)))))
(build-table #(* % %) [:lower 2 :upper 6 :step 2])
;; '(4 16 36)
(build-table #(+ (* 10 %) %2) [:lower 1 :upper 4]
[:lower 1 :upper 3])
;; '((11 12 13) (21 22 23) (31 32 33) (41 42 43))
答案 1 :(得分:0)
我认为您可以使用map
和range
(defn applier
[f ini max step]
(map f (range ini (+ max step) step)))
(applier #(* % %) 2 6 2)
=> (4 16 36)
答案 2 :(得分:0)
这个fn可以解决你的第三个例子
(defn your-fn [[ra1 ra2] [rb1 rb2] the-fn]
(vec (map (fn [i] (vec (map (fn [j] (the-fn i j)) (range rb1 (inc rb2))))) (range ra1 (inc ra2))))
)
(your-fn [1 4] [1 3] (fn [i j] (+ (* 10 i) j)))
=> [[11 12 13] [21 22 23] [31 32 33] [41 42 43]]
但是我需要更多规范细节(或更多用例)来使这种行为变得通用,也许你可以解释一下你的问题。我认为第1和第2个例子不采用相同类型的参数和含义,(步骤与seq)。因此,@ Guillermo-Winkler解决了问题,而my-fn将涵盖最后一个例子