如何返回传递给Clojure函数的空集合的值

Seb*_*ian 1 clojure destructuring

我有一些函数可以从传递的映射返回一些键的最大值.我希望0在传递集合为空时返回.当然我可以使用一些条件,但想知道是否有更先进的技术呢?

(defn max-id [c]
  "Using as: (max-id [{ :id 1 }, { :id 2 }])"
  (if (empty? c)
    0
    (apply max (map :id c))))
;;;
(max-id []) => 0
(max-id [map-one map-two]) => 1024
Run Code Online (Sandbox Code Playgroud)

Jos*_*osh 5

具有讽刺意味的是,"高级"是大多数高级程序员在可能的情况下往往会避免的,通常会在可能的情况下选择简单.这里的底线是你的功能很好,因为一个原因:你的意图很明确.每个人都可以理解如果传入空集合会发生什么,即使他们不是程序员也是如此.这是一个巨大的好处,使您的解决方案已经是一个理想的解决方案,至少就空集合情况而言.

现在,如果你可以保证:id给定集合中至少有一个s为零或更大的约束(即,我们正在处理正数ids),那么你可以这样做:

(defn max-id [c]
  (reduce max 0 (map :id c)))
Run Code Online (Sandbox Code Playgroud)

但是,如果您有一个所有具有否定ID 的地图列表,这不起作用,即: [{:id -1} {:id -2}],因为在这种情况下,max-id应该是-1,因此上述内容不会产生正确的答案.

还有其他解决方案,但它们涉及条件检查,即使它有点隐含.例如:

(defn max-id [c]
  (apply max (or (not-empty (map :id c)) [0])))
Run Code Online (Sandbox Code Playgroud)

我不推荐的一个选项涉及替换max一个带有0或更多args的函数,检查是否有任何args,max如果有,则调用,如果没有则返回0.除非你有这将需要一些其他的用例max什么是零,我会避免这样做,所以我还没有要发布它.这变得过于复杂,需要读者去挖掘,所以不要这样做.

顺便说一句,有一个核心功能,这个功能并不是众所周知的,在列表中找到给定键值最大的元素可能更为惯用.它被称为max-key:

(defn max-id [c]
  (:id (apply max-key :id c)))
Run Code Online (Sandbox Code Playgroud)

但是,我会说你的功能更容易理解,如果没有其他原因而max-key不是众所周知的maxmap.所以,只需将它作为一个额外的选项给你.