【问题标题】:Choice of data model: Nested map or vector for Reagent atom to be updated-in and mapped over?数据模型的选择:要更新和映射的试剂原子的嵌套映射或向量?
【发布时间】:2020-07-17 06:09:00
【问题描述】:

我正在开发一个 Reagent 应用程序来管理酒店预订网站的季节。数据显示在表格视图中,当前存储在一个原子中,其中包含一个以季节 ID 作为键的嵌套地图,如下所示:

(def seasons (r/atom
{1
 {:begin "2020-04-02"
  :end "2020-04-19"
  :selected false
  …much more data like price per room etc}
2
{:begin "2020-04-20"
  :end "2020-06-18"
  :selected true
  }
…}))

这种结构的主要优点是通过 #(dissoc @seasons season-id)(update-in seasons [season-id :begin] "2020-04-21") 从我的组件中轻松删除/修改季节,如果将 id 集成到表示季节的地图中,这将更加麻烦,例如所以:

(def seasons
(r/atom
[{:id 1
  :begin "2020-04-02"
  :end "2020-04-19"
  :selected false
  …much more data like price per room etc}
 {:id 2
  :begin "2020-04-20"
  :end "2020-06-18"
  :selected true
  }…]))

这个版本更适合被映射,这对我当前的数据模型来说不是很愉快,我必须总是将 id 与实际映射重新组合成一个二进制向量,然后将生成的 seq 粘贴回来@ 987654328@一张地图。

我越来越倾向于切换到第二个模型,因为通过将整个赛季传递给一个函数来删除/更新是可行的……那时根本不需要 id,例如:

(vec (remove #(= % season) @seasons))

或者,分别:

(vec (map #(if (= % season) 
       (update-in % [:begin "2020-04-21"]) %) @seasons))

由于这是我的第一个真实世界的 Reagent 应用程序,我有点不确定哪种数据模型实际上更可取?两种方法之间是否有任何性能考虑?对于经验丰富的试剂开发人员来说,哪一个看起来更理智?是否有我不知道的第三种方式?

非常感谢您对这个有点开放的问题的任何意见!

【问题讨论】:

  • 因修改嵌套数据结构并保持其结构而获得荣誉奖:github.com/redplanetlabs/specter
  • 谢谢,我已经打算研究幽灵一段时间了……但对于我目前的项目来说,这可能是矫枉过正。

标签: data-structures clojure clojurescript reagent


【解决方案1】:

当您描述您的目的(季节)时,性能不是一个考虑因素。每天三个“季节”每年只有约 1000 个 - 对于计算机而言,这是一个很小的数字。

那么,哪种方法更适合您的代码?您已经讨论了两个用例,在一种情况下支持方法 A,在另一种情况下支持方法 B。由您决定。

在方法 A 中,您已经“预先索引”了数据,因此您可以直接进入某个事物并对其进行修改。在方法 B 中,您必须在处理之前进行小型搜索以找到事物。对于更大的问题,方法 B 最终会演变为 Postgres、Datomic 或 Neo4J 等 DB。

对于留在内存中的小问题,您可以使用库:

这些在现阶段可能有点矫枉过正,但您可能希望将来记住它们。

【讨论】:

  • 非常感谢您的判断……我知道,在更高级的 Clojurian 眼中,选择并不像我想象的那么明显,而且我看到的权衡实际上是真实的并且不容易绕过……我想我会尝试重构为 B 版……即使只是为了学习目的。 Tupelo.Forest 看起来很棒……可能会解决我一直在做的一些打嗝走路的尝试。
猜你喜欢
  • 1970-01-01
  • 2014-04-30
  • 2012-08-29
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多