1

我正在编写一个重新构建应用程序来模拟棋盘游戏,其中我有一个包含一组单元格的棋盘结构,例如:

{... :board-cells [{:name "cell-1" :material #object} {:name "cell-2" :material #object} ...]}

(db :board-cells)虽然re -frame 支持使用漂亮的关键字语法((get (nth (db :board-cells) index) :material)如 这也有将我的数据库的物理布局与我的应用程序逻辑紧密耦合的缺点。如果我决定改变我的数据库结构怎么办?然后我必须更新十个不同的点,而不仅仅是一个。

是否有一种重新构建官方方法来创建“虚拟查询”,这样我就可以获得类似的材料(db :get-nth-mat n),其中 n 是board-cells数组中的单元格编号?我认为这是我可以做到db.cljsreg-sub地方,但它似乎不起作用。是的,我可以创建自己的吸气剂:

(defn get-material [db index]
  (get (nth (db :board-cells) index) :material))

并称它为(println "mat-4=" (cell/get-material db 4)),但这并不像(db :get-nth-mat n)

非常感谢。

4

1 回答 1

1

db只是一张地图,这个“功能”与重新框架无关,但每张地图都是一个功能,关键字也是如此。所以当你做(map something)或者(:keyword something)你实际上在做 时(get map something)(get something :keyword)

doseq因此,除了以不同方式访问/迭代您的数据(例如,、、、 ...)之外for,实际上没有“捷径” map——假设您要逐个单元格地渲染网格;这样你就完全摆脱了基于索引的访问。

否则我会使用像你这样的专用函数,但宁愿命名它material-by-idx(命名函数getset像 OO 中的访问器是相当不常见的(但有一些地方,例如设置状态修改))。

正确命名的、理想的纯函数,正确地做一件事是函数式和 Lisp 编程的重要组成部分。通常,必须输入更多内容的不利影响可以通过更高级别的编程范例(如线程或部分应用程序或作为最后手段的宏)来缓解。

你可以用get-in它来整理一下:

(defn material-by-idx [db idx]
  (get-in db [:board-cells idx :material]))

例如,如果你看到其中的价值,你现在可以在你的循环中使用这样的东西:

(let [mat-at (partial material-by-idx db)]
  (mat-at 5))

顺便说一句:您想要的版本(db :get-nth-mat n)确实有效(但不是您想要的)。它变成(get db :get-nth-mat n)(3 个参数),如果没有键 ,get它会返回你。n:get-nth-matdb

于 2020-01-03T09:28:11.257 回答