繁体   English   中英

通过多个键对Clojure进行分组

[英]Clojure grouping by multiple keys

使用分组方式时出现问题。 这是代码

(defn combine-by-coords
  [values]
  (let [grouped-by-x (group-by :x values)]
     (persistent!
     (reduce (fn [res x-val]
               (assoc! res x-val (group-by :y (x-val grouped-by-x))))
             (transient {})
             (keys grouped-by-x)))))

地图值的形式为

{:x 754, :y 56, :someKey "zxyf" ....} .

该代码的目的是将具有相同x和y值的地图分组在一起。 首先,我使用内置的分组依据功能将x值分组在一起,结果是

{754 [{....}, {....}]} 

之后,我将按键的y值对键754的数组进行分组。 但是,这是我得到错误的地方。 似乎无法使用键754。这是我收到的错误:

java.lang.Integer cannot be cast to clojure.lang.IFn

我也尝试过使用(关键字名称)函数从中创建一个关键字,但这也不起作用。

是否有人知道该问题的解决方案,或者知道重写我的代码的方法? 最后,我只需要将具有相同x和y的映射分组即可。

您不能使用像关键字这样的数字。 您必须使用get

user=> (5 {5 :x})
#<CompilerException java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (REPL:1)>
user=> ({5 :x} 5)
:x
user=> (get {5 :x} 5)
:x

在您的情况下:将(x-val grouped-by-x)(get grouped-by-x x-val)交换。

或者您可以摆脱x-val(关键):

(defn combine-by-coords
  [values]
  (let [grouped-by-x (group-by :x values)]
     (persistent!
     (reduce (fn [res [x-key vals]]
               (assoc! res x-key (group-by :y vals)))
             (transient {})
             grouped-by-x))))

尝试使用#(= (key %) 754)代替754作为group-by的第一个参数。

问题在于,group-by的第一个参数需要是一个要为您要分组的值返回true的函数。 关键字可以用作函数,因此它们可以很好地工作,但是当然整数不是函数,因此我们需要编写一个进行比较的函数。

注意,这提供了很大的灵活性,例如

Clojure> (group-by even? (range 10))
{true [0 2 4 6 8], false [1 3 5 7 9]}

更新:看来这不是所讨论的代码的问题,但是我会留下这个答案,以防万一有人遇到类似的问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM