Data structures 具有选定项的Clojure集合原子

Data structures 具有选定项的Clojure集合原子,data-structures,functional-programming,clojurescript,reagent,Data Structures,Functional Programming,Clojurescript,Reagent,Clojure(实际上是ClojureScript)实现以下目标的最佳方式是什么: 元素的可变集合xs,每种类型T(T是一个映射,如果我们想具体化) 其中的“选定元素”x,在各种xs或“未选定”状态之间交替。所选项目的数量为1或零 xs和x将有事件侦听器侦听它们:一些侦听xs中的任何更改;有些人监听x中的任何更改。(也就是说,它们会侦听所选项目状态的更新,以及所选项目的切换。)(我实际上使用试剂包装器进行React,因此这会影响组件更新的时间。) 编辑x的方法(不需要编辑未选择的xs,但需要能

Clojure(实际上是ClojureScript)实现以下目标的最佳方式是什么:

  • 元素的可变集合
    xs
    ,每种类型
    T
    T
    是一个映射,如果我们想具体化)
  • 其中的“选定元素”
    x
    ,在各种
    xs
    或“未选定”状态之间交替。所选项目的数量为1或零
  • xs
    x
    将有事件侦听器侦听它们:一些侦听
    xs
    中的任何更改;有些人监听
    x
    中的任何更改。(也就是说,它们会侦听所选项目状态的更新,以及所选项目的切换。)(我实际上使用试剂包装器进行React,因此这会影响组件更新的时间。)
  • 编辑
    x
    的方法(不需要编辑未选择的
    xs
    ,但需要能够添加新的
    xs
  • 给定
    xs
    中的一个元素,选择该元素的方法。(包括选择“无”的情况)
到目前为止,我想到的可能性是:

  • 使
    xs
    成为一个原子,它是
    T
    s的向量,并确保每个
    T
    元素都知道自己的索引。将
    x
    替换为存储所选项目索引的
    x_idx
    (或
    nil
    )。选择一个元素只意味着获取它的索引并将
    x_idx
    更改为该索引,这两种操作都是固定时间操作。这样做的缺点是,它使结构变得不那么优雅和简单:我总是传递所选项的索引,我想做的每一个操作都必须使用索引,而不是项目本身,正如它所希望的那样。因为我的
    T
    对象很小,所以如果有一个类型为
    T
    的“selected object”变量就更好了
  • 使
    xs
    成为一个原子向量,
    x
    成为一个存储
    T
    的原子。现在
    x
    是一个
    T
    ,这很好,但是当我想更新
    x
    的信息时,我必须打两个电话来重置
    reset
    交换:一个用于
    x
    ,另一个用于
    xs
    x
    表示的元素。因为明显的原因而不雅。我必须快速连续地执行这些操作,否则数据将不一致:在两次调用之间,收听
    xs
    的事件侦听器将在一种状态下看到所选项目,而收听
    x
    的事件侦听器将在另一种状态下看到它
  • T
    元素一个字段,告诉它们是否被选中,并去掉
    x
    。如果一次可以选择多个项目,这将是正确的,但由于只能选择一个项目,因此每次需要所选项目时,我都会进行线性搜索,这很糟糕

  • 这个问题的重点不是要解决某个特定的问题(以上任何一种可能性都适用于我正在处理的小项目),而是要了解Clojure数据结构。这似乎是一种很常见的情况,因此它周围会有一些结构。欢迎回答“您应该尝试回答完全不同的问题…”。

    您(我)想了解
    光标
    s和
    反应
    s,这是试剂原子的两个更高级的功能。它们可以用于在其中包含一个集合和一个自动更新的选定元素。例如,见

    假设您有一个容纳对象向量的
    r/atom
    ,并且您希望有一个可以更改且可直接编辑的选定对象。实现这一点的一种方法是让一个原子存储所选项目的索引,然后

    (定义我的设置
    ([_k](@vector of items@idx of selected item))
    ([_kv](gent.core/rswap!我的状态向量assoc@idx of selected item v)))
    (定义所选项目(试剂.core/cursor my get set[]))
    

    编辑:
    reagent.core/cursor my get set nil
    更改为
    reagent.core/cursor my get set[]
    。前者会导致问题。

    您可能希望提供一些代码示例,说明您将进行哪些函数调用、预期结果等。到目前为止,您为解决此问题而编写的最佳代码是什么?1。地图是不可变的。2.如果这个数据结构将被修改,那么使其可变可能不是最好的主意。3.事件侦听器?怎么用?我假设这些不是原始DOM节点。4.这整件事听起来像是对一个选择元素的抽象,这就是你想要的吗?5.你是对的,这整件事听起来有点离谱(不是完全离谱,而是以某种方式扭曲)。你能给我们一些实际的代码,以及为什么它能工作或不能工作吗?“这个问题的重点不是解决某个特定的问题”,这就是问题的全部要点。这应该分成五个问题,包括你的研究和每一个问题的尝试。此外,Hickey(Clojure的创建者,icydk)在p。在他2020年的论文中,@JaredSmith一张地图是不可变的,但是一个原子的状态是一组地图的集合,正如我所说的,它是可变的。我同意我的问题可以通过一些代码来改进。