[英]Building tables in clojure
If I wanted to build a table in Clojure of vector duplicates, I'd write: 如果我想在矢量重复的Clojure中建立一个表,我会写:
(take 2 (repeat [1 2 3]))
But how would I expand this notion of a table function to build something like: 但是我将如何扩展表函数的概念来构建类似以下内容的东西:
Input 1: [a^2 2 6 2] where a^2 is some input function, 2 is min value, 6 is max value, and 2 is step size. 输入1:[a ^ 2 2 6 2]其中a ^ 2是某些输入函数,2是最小值,6是最大值,2是步长。
Output 1: [4,16,36] 输出1:[4,16,36]
Input 2: [b^2 10 -5 -2] 输入2:[b ^ 2 10 -5 -2]
Output 2: [100 64 36 16 4 0 4 16] 输出2:[100 64 36 16 4 0 4 16]
This outputs a 4x3 matrix 输出4x3矩阵
Input 3: [(+ (* 10 i) j) [1 4] [1 3]] 输入3:[(+(* 10 i)j)[1 4] [1 3]]
where (+ (* 10 i) j) is 10i+j (some given input function), [1 4] is the min and max of i, and [1 3] is the min and max of j. 其中(+(* 10 i)j)是10i + j(某些给定的输入函数),[1 4]是i的最小值和最大值,[1 3]是j的最小值和最大值。
Output 3: [[11 12 13] [21 22 23] [31 32 33] [41 42 43]] 输出3:[[11 12 13] [21 22 23] [31 32 33] [41 42 43]]
You want to use for
in a nested fashion: 你想用
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))
EDIT: expanded with an example implementation 编辑:扩展与示例实现
For example: 例如:
(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))
Your three input/output samples do not display a consistent signature for one variable and two ; 您的三个输入/输出样本对于一个变量和两个变量没有显示一致的签名。 furthermore, the
step
argument seems to be optional. 此外,
step
参数似乎是可选的。 I'm skeptical about the existence of a nice API that would retain the samples' syntax, but I can try something different (even if I do believe the simple embedded for
forms are a better solution): 我怀疑一个很好的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))
I think you can easily solve it with map
and range
我认为您可以通过
map
和range
轻松解决它
(defn applier
[f ini max step]
(map f (range ini (+ max step) step)))
(applier #(* % %) 2 6 2)
=> (4 16 36)
This fn can resolve your third example 这可以解决您的第三个例子
(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]]
But i'd need a few more specification details (or more use cases) to make this behavior generic, maybe you can explain a little more your problem. 但是我需要更多规范细节(或更多用例)来使这种行为通用,也许您可以解释更多问题。 I think the 1st-2nd and the 3rd examples don't take the same type of parameters and meaning, (step vs seq ).
我认为第一和第二和第三示例没有采用相同类型的参数和含义(step vs seq)。 So the @Guillermo-Winkler solves part the problem and my-fn will cover the last example
因此,@ Guillermo-Winkler解决了部分问题,而my-fn将覆盖最后一个示例
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.