0

如果我想在 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]]

4

3 回答 3

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))
于 2013-11-30T04:05:14.343 回答
0

map我认为你可以很容易地解决它range

(defn applier
  [f ini max step]
  (map f (range ini (+ max step) step)))

(applier #(* % %) 2 6 2)
=> (4 16 36)
于 2013-11-21T02:39:03.427 回答
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 和第 3 个示例不采用相同类型的参数和含义(step vs seq)。所以@Guillermo-Winkler 解决了部分问题,my-fn 将涵盖最后一个示例

于 2013-11-21T12:30:26.540 回答