clojure - 嵌套测试的功能版本是什么?
问题描述
我正在将一些 C++ 代码转换为 Clojure,并且我想返回一个g
添加了一堆边的图。我传入了顶点数、图形和测试谓词(例如,一个可能依赖于 i、j、随机性...的函数),如下所示:
(defn addSomeEdges [v g test-p]
(doseq [i (range v)]
(doseq [j (range (dec i))]
(if test-p
(add-edges g [i j] )
)))
g)
当然,问题是(add-edges)
返回一个新的g
. 请问如何使用 Clojure 最佳实践来捕获这个更新的图表?在 C++ 中,它看起来如此简单和自然。
解决方案
如果将信息拆分为两部分,则迭代地累积信息看起来像一个缩减函数:
- 生成一堆边来考虑包括在内。
- 测试每个边缘,如果它通过,包括它。否则将结果不变地传递
可以使用reduce
user> (defn add-edge [g i j]
(assoc g i j))
#'user/add-edge
user> (add-edge {1 2} 2 1)
{1 2, 2 1}
user> (defn addSomeEdges [v g test-p]
(reduce (fn [graph [i j]] ;; this takes the current graph, the points,
(if (test-p graph i j) ;; decides if the edge should be created.
(add-edge graph i j) ;; and returns the next graph
graph)) ;; or returns the graph unchanged.
g ;; This is the initial graph
(for [i (range v)
j (range (dec i))]
[i j]))) ;; this generates the candidate edges to check.
#'user/addSomeEdges
让我们运行它!
user> (addSomeEdges 4 {1 2} (fn [g i j] (rand-nth [true false])))
{1 2, 2 0}
user> (addSomeEdges 4 {1 2} (fn [g i j] (rand-nth [true false])))
{1 2, 3 0}
user> (addSomeEdges 4 {1 2} (fn [g i j] (rand-nth [true false])))
{1 2, 2 0, 3 1}
当您想到其他测试时,您可以将这些调用串联在一起:
user> (as-> {1 2} g
(addSomeEdges 4 g (fn [g i j] (rand-nth [true false])))
(addSomeEdges 7 g (fn [g i j] (< i j)))
(addSomeEdges 9 g (fn [g i j] (contains? (set (keys g)) j))))
{1 2, 3 1, 4 1, 5 3, 6 4, 7 5, 8 6}
推荐阅读
- html - 如何使 CSS 模板 w3schools 内容高度 100%
- ruby-on-rails - Capistrano rbenv deploy 卡住并且不打印任何内容
- reporting-services - SSRS - 加载报告时用户出错
- java - 程序不会打印任何东西,直到 Scanner#nextLine() 没有收到“空白”或“输入”
- rust - 如何获取 rust-sdl2 窗口表面并同时使用事件迭代器?
- json - 在 Firebase 实时数据库中为 ChildByAutoID 编写规则?
- webpack - “Webpack 模块”的定义
- google-sheets - 谷歌表格迷你条形图水平
- ag-grid - AgGrid 版本 22.1 和 Angular 10
- java - Python中的整数变量是否保存指向内存中int对象的指针?