2013-10-07 60 views
1

我试图从SQL查询中将最大和最小结果拉到Clojure中,以便我可以对它们执行数学分析,但我不确定为什么出现错误。在Clojure中获取最大值和最小值

我已经使用代码中的最大和最小函数来尝试并确定这些结果,尽管我不断收到两条似乎与我使用:计数器关键字的方式有关的错误。

从SQL查询地图返回的数据是这样的:

{:date1 "20131007", :data "object1", :counter 1000} 
    {:date1 "20131007", :data "object2", :counter 50} 
    {:date1 "20131007", :data "object3", :counter 230} 

当我使用此代码:

minvalue(min(map(keyword :counter)data2)) 
    maxvalue(max(map(keyword :counter)data2)) 
    valrange(- maxvalue minvalue) 
    valpc(* (/ valrange 100) 10) 
    x(- maxvalue valpc) 

我当然希望MINVALUE被设置为50和maxvalue设置为1000虽然我得到此错误:

java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to java.lang.Number 

如果我删除从代码中的地图功能,然后再次运行它,我得到这个错误:

java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.lang.Number 

任何帮助表示赞赏这是我完全被卡住(和它可能非常ovbious我”我是Clojure的新手)!由于

+1

甲分解出来的共同性关于性能的注意事项:如果你有更多的地图要处理,使用reduce(像'(reduce min(:counter(first maps))(map:counter(rest maps)))')会比应用更有效率。 – noisesmith

回答

6

从您的代码进行少许修改:

  • 最小值和最大值带可变数量的参数,而不是一个集合。使用apply可以很好地将集合的内容作为参数应用。
  • Clojure的命名约定使用 - 词之间
  • 有效来电必须是这样的形式(基本上,其中第一项是可调用列表)
  • 没有必要使用“关键词”,关键词是当你有一个字符串并需要关联的关键字。用于拖动数据出地图的关键字作为函数本身例如(:一个{:1:B 2})返回1
  • 在您的前两行

    (def data [{:date1 "20131007", :data "object1", :counter 1000} 
          {:date1 "20131007", :data "object2", :counter 50} 
          {:date1 "20131007", :data "object3", :counter 230}]) 
    
    (def counters (map :counter data))  ; => (100 50 230) 
    (def min-value (apply min counters)) ; => 50 
    (def max-value (apply max counters)) ; => 1000 
    (def val-range (- max-value min-value)) ; => 950 
    (def val-pc (* (/ val-range 100) 10)) ; => 95 
    (def x (- max-value val-pc))   ; => 905 
    
3
user=> data 
[{:data "object1", :date1 "20131007", :counter 1000} {:data "object2", :date1 "20131007", :counter 50} {:data "object3", :date1 "20131007", :counter 230}] 

user=> (apply max-key :counter data) 
{:data "object1", :date1 "20131007", :counter 1000} 

user=> (apply min-key :counter data) 
{:data "object2", :date1 "20131007", :counter 50} 
+0

谢谢,我只是试过上面的代码,我仍然收到错误:java.lang.ClassCastException:clojure.lang.LazySeq不能转换为java.lang.Number。我只查找来自:计数器键的实际整数值,以便我可以处理实际值。再次感谢你的帮助! – Paul

+1

如果您只想使用'(apply min(map:counter data))'或'(reduce min(map:counter data))''。上面的代码和此代码的作品。数据应该是地图的矢量。 – defhlt

相关问题