【问题标题】:How to validate/filter new elements to be conj (added) to collection in clojure如何验证/过滤要 conj(添加)到 clojure 中的集合的新元素
【发布时间】:2014-06-16 08:39:47
【问题描述】:

我需要为要添加/合并到集合中的新元素提供验证规则。 此规则将是与集合中已存在的元素的特定比较。

例如如果我的集合是一个排序集,我不仅需要 conj 接受的唯一元素,而且在其他特定情况下它们应该是唯一的:)

我的具体情况如下(不要批评我的例子:)这与现实相去甚远):

我有一组山脊(“山中的窥视链”)作为它们在不同时间“窥视”的向量:)

例如

很多年前,山中有一座山脊:#{[1 0 2 0]}

多年前又长出了一条山脊:#{[1 0 2 0] [2 0 1 0]}

现在...我想只允许添加以下规则可接受的山脊:

  • 在同一“向量中的位置”处,有效的山脊至少应比其他山脊的至少一个窥视点高一倍。

例如在我们的最后一个案例#{[1 0 2 0][2 0 1 0]}

有效的山脊是:[0 0 0 1][0 1 0 0][0 1 0 1][3 0 1 0] [1 0 3 0] [1 1 2 0] [2 0 1 1] [2 1 1 0] 等...

无效的山脊是:[1 0 1 0] [0 0 1 0],等等...

简而言之,我们只接受“至少在某个地方”具有更高窥视的山脊 :)

问题是: 在 clojure 中实现这种验证的更好方法是什么?

  • 扩展集合(集合、排序集合)以验证除了唯一性之外还有“我奇怪的高度唯一性?如何做到这一点?
  • 实现我自己的集合?
  • 只是每次在 conj 收集之前,使用 if 和验证功能?
  • 使用一些可用的 clojure 功能?例如,您可以将自定义比较器添加到 sorted-set-by。问题是 - 是否可以提供一些自定义的“验证规则”?有没有合适的 clojure 库?
  • 还有其他想法吗?

【问题讨论】:

    标签: validation collections clojure


    【解决方案1】:

    创建一个新的集合类型有点乏味,但是一个(?)正确的解决方案(不要忘记实现读取/打印,标签文字可能会有所帮助)。

    在每个 conj 之前执行 if 不是最理想的,因为为了提高效率,您可能需要在集合上维护一些属性:在您的示例中,您可能希望保持向量中每个位置的最小高度(因此允许决定是否在 O(1) 而不是 O(n)) 中添加项目。

    你至少可以做一个conj-ridge函数:

    (defn conj-ridge [[ridges min-heights :as ridges-set] ridge]
      (if (= (map max min-heights ridge) min-heights)
        ridges-set
        [(conj ridges ridges) (map min min-heights ridge)])) 
    

    【讨论】:

      【解决方案2】:

      你可以使用前置条件:

      (defn higher-peak? [old-ridge new-ridge]
        (some #(> (new-ridge %) (old-ridge %)) 
              (range (count old-ridge))))
      
      (defn conj-ridge [ridges ridge]
        {:pre [(some #(higher-peak? % ridge) ridges)]}
        (conj ridges ridge))
      

      每当您尝试使用conj-ridge 添加没有更高峰值的山脊时,这将引发 AssertionError。如果您不希望出现错误,您可以编写一个高阶函数,将对 conj-ridge 的调用包装在 try/catch 块中:

      (defn conj-ridge-if-valid [ridges ridge]
        (try 
          (conj-ridge ridges ridge)
          (catch AssertionError e ridges)))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多