【发布时间】:2021-01-31 18:40:40
【问题描述】:
在 Clojure(实际上是 ClojureScript)中完成以下任务的最佳方式是什么:
- 一个可变的元素集合
xs,每个类型为T(T是一个映射,如果我们想具体一点的话) - 其中一个“选定元素”
x,在各种xs或“未选定”状态之间交替。所选项目的数量为 1 或 0。 -
xs和x将有事件监听器监听它们:一些监听xs的任何变化;有些人会听x的任何变化。 (也就是说,它们监听所选项目状态的更新,以及选择哪个项目的切换。)(我实际上使用 React 的 Reagent 包装器,所以这会影响组件何时更新。 ) - 编辑
x的方法(不需要编辑未选中的xs,但需要能够添加新的xs) - 给定
xs中的一个元素,选择它的方法。 (包括选择“无”的情况)
到目前为止我想到的可能性:
- 使
xs成为Ts 的向量的原子,并确保每个T元素都知道自己的索引。将x替换为x_idx,它存储所选项目的索引(或nil)。选择一个元素只是意味着获取它的索引并将x_idx更改为该索引,这两者都是恒定时间操作。这样做的缺点是它使结构不那么优雅和简单:我总是传递所选项目的 index,而我想做的每一个操作都必须使用索引来代替项目本身,如它所愿。由于我的T对象很小,所以如果有一个T类型的“选定对象”变量会更令人愉悦。 - 将
xs设为原子向量,将x设为存储T的原子。现在x是T,这很好,但是当我想更新有关x的信息时,我必须两次调用reset!或swap!:一个用于x,一个用于xs中的元素,x代表。不优雅的原因显而易见。我必须快速连续执行这些操作,否则数据会出现不一致:在两次调用之间,监听xs的事件监听器将看到选定的项目处于一种状态,而监听@987654356 的事件监听器将看到@ 会在另一个状态下看到它。 - 给
T元素一个字段来判断它们是否被选中,并去掉x。如果可以一次选择多个项目,这将是正确的,但由于只能选择一个项目,它只会让我每次想要选择的项目时都进行线性搜索,这很糟糕。
这个问题的重点不是解决某些特定问题(上述任何可能性都适用于我正在从事的小型项目的范围),而是要了解 Clojure 数据结构。这似乎是一种很常见的情况,周围会有一些结构。欢迎使用“您应该尝试完全回答一个不同的问题......”这样的回答。
【问题讨论】:
-
您可能希望提供一些代码示例,说明您将进行哪些函数调用、预期结果等。到目前为止,您为解决此问题编写的最佳代码是什么样的?
-
1.地图是不可变的。 2. 如果这个数据结构要支持 React,让它可变可能不是最好的主意。 3. 事件监听器?如何?我假设这些不是原始 DOM 节点。 4. 这整个事情听起来像是对选择元素的抽象,这就是你想要的吗? 5. 你说得对,这整件事听起来有点离谱(不完全存在,但以某种方式歪曲)。你能给我们一些实际的代码以及为什么它可以工作或不工作吗?
-
“这个问题的重点不是解决某个特定问题”,这就是 SO 的全部意义所在。这应该分成五个问题,每个问题都有你的研究和尝试。此外,Hickey(Clojure 的创建者,icydk)在 p. 上讨论了 Clojure 的数据结构。他 2020 年论文中的 6 篇,"A History of Clojure"。
-
@JaredSmith 映射不是可变的,但如我所述,其状态是映射集合的原子是可变的。我同意我的问题可以通过一些代码来改进。
标签: data-structures functional-programming clojurescript reagent