如何对键为字符串而非关键字的嵌套Map使用sort-by函数?
如何对键为字符串而非关键字的嵌套Map使用sort-by函数?
你猜的没错!问题确实出在关键字可以直接作为函数来取值,但字符串不行——Clojure里字符串没有实现IFn接口,所以没法像关键字那样直接塞进comp里当函数用,这才抛出了那个ClassCastException。
解决这个问题的核心就是换一种方式从嵌套Map里取出"rank"对应的值,不用字符串当函数就行,这里有几种常用的方法:
方法一:用匿名函数配合get替代字符串
把原来的"rank"换成一个匿名函数,用get来取值:
(sort-by (comp #(get % "rank") second) > {:1 {:bar "something" "rank" 10} :2 {:bar "other" "rank" 20}})
这里#(get % "rank")会接收second返回的嵌套Map,然后用get取出键为"rank"的值,完美替代了关键字作为函数的作用。
方法二:用partial简化写法
如果觉得匿名函数有点啰嗦,可以用partial创建一个偏函数,固定get的第二个参数为"rank":
(sort-by (comp (partial get "rank") second) > {:1 {:bar "something" "rank" 10} :2 {:bar "other" "rank" 20}})
(partial get "rank")相当于生成了一个新函数,它接收一个Map参数时,会自动执行(get map "rank"),效果和匿名函数完全一样,代码更简洁。
方法三:直接在排序函数里解构键值对
如果不想用comp,也可以直接把逻辑写在sort-by的第一个参数里,解构每个键值对的value,再取值:
(sort-by (fn [[k v]] (get v "rank")) > {:1 {:bar "something" "rank" 10} :2 {:bar "other" "rank" 20}})
这种写法更直观,一眼就能看出是从每个键值对的value部分取出"rank"的值,对新手友好度更高。
这几种方法都能解决你的问题,选你觉得最易读的就行~
备注:内容来源于stack exchange,提问作者triplej
相关产品推荐
相关产品推荐

