我正在尝试为集合向量创建一个累加器函数。但是我总是得到奇怪的结果

I am trying to create an accumulator function for an vector of sets. But I keep getting strange results

提问人:Braden Christopher 提问时间:10/25/2023 更新时间:10/26/2023 访问量:101

问:

基本上,我有一个集合向量。我想根据条件合并集合(您可以在 if 语句中看到此条件)。可以合并两个以上的集合。下面是一个示例数据集:

[{:name "corner", :matched-shape "corner", :direction :e, :rotation 1}
                                        {:name "corner", :matched-shape "corner", :direction :e, :rotation 2}
                                        {:name "corner", :matched-shape "corner", :direction :s, :rotation 2}
                                        {:name "corner", :matched-shape "corner", :direction :s, :rotation 3}
                                        {:name "corner", :matched-shape "pipe", :direction :s, :rotation 0}
                                        {:name "corner", :matched-shape "pipe", :direction :e, :rotation 1}
                                        {:name "corner", :matched-shape "pipe", :direction :s, :rotation 2}
                                        {:name "corner", :matched-shape "pipe", :direction :e, :rotation 3}
                                        {:name "corner", :matched-shape "cross", :direction :e, :rotation 0}
                                        {:name "corner", :matched-shape "cross", :direction :s, :rotation 0}
                                        {:name "corner", :matched-shape "cross", :direction :e, :rotation 1}
                                        {:name "corner", :matched-shape "cross", :direction :s, :rotation 1}]

我尝试了几十种解决方案,但没有一种有效。这是我的代码:

(defn merge-symmetry-table [symmetry-table]
  (filter #(if-not (nil? %) %) 
          (loop [[x y & remaining] symmetry-table result []]
            (if-not (empty? y)
              (if (and (= (:name x) (:name y))
                       (= (:direction x) (:direction y)))
                (recur [(concat-symmetries x y) remaining] result)
                (recur [conj y remaining] [result x]))
              (conj result x)))))

以及我截至现在的输出:

([]
 {:name "corner", :direction :e, :matched-shapes ["corner" 1 "corner" 2]}
 {:name nil, :direction nil, :matched-shapes [[nil nil nil nil] nil nil]})

我确信有一种更好的方法可以做到这一点,但我想知道我的代码到底出了什么问题。我已经看了五十遍了,我不明白出了什么问题。谢谢你的帮助。

我不确定我是否被允许在这里表达不满(我不想打扰任何人),但我在这种编程语言中处理数据时遇到了绝对巨大的困难。诚然,这是我用这种语言的第一个项目,我主要是一个自学成才的程序员。但是,将向量嵌套在向量中并仅使用“键盘映射”使它成为一场噩梦,试图完成任何事情,更不用说以有凝聚力的方式组织数据了。我可能重写我的函数至少十次,只是为了让它们返回我想要的东西。我一定错过了什么。

函数式编程 Clojure 数据挖掘

评论

2赞 akond 10/25/2023
输出应该是什么?

答:

3赞 Rulle 10/25/2023 #1

您可能希望使用以下任一方法:partition-by

(defn merge-symmetry-table [data]
  (->> data
       (partition-by (juxt :name :direction))
       (map (partial apply concat-symmetries))))

或:group-by

(defn merge-symmetry-table [data]
  (->> data
       (group-by (juxt :name :direction))
       vals
       (map (partial apply concat-symmetries))))

评论

0赞 Braden Christopher 10/26/2023
group-by 似乎以我需要的方式组织结果。但是,我的 concat-symmetries 函数通过一次输入两个条目来工作。它意味着一种适用于成对的累加器。如果参数符合条件,它将将它们合并在一起。否则,它将打印出先前合并的对,并重新开始接下来的两个参数。这确实是我在实现时遇到困难的逻辑部分。
0赞 Braden Christopher 10/26/2023 #2

多亏了这个建议,我才能够找到一个解决方案。它使用建议的代码,我将我的 concat 函数重新表述为化简器,它可以工作!这是我的代码:

(defn merge-symmetry-table [data]
  (let [symmetry-table (sort-by (juxt :name :direction) data)]
    (->> symmetry-table
         (partition-by (juxt :name :direction))
         (map #(reduce concat-symmetries %)))))