如何在 clojure 中为 '() 编写 max 函数

How to write a max function in clojure for a '()

几天前我对 Clojure 还很陌生。 我正在尝试创建一个必须按以下方式工作的 my-max 函数 (my-max '(8 18 98 55 4 5 6)) => 98

我看过其他类似的问题,例如 Defining my own max function with variable arguments

我尝试编写类似 post 中的函数,但我不明白为什么它们在用括号编写时不起作用,例如 (my-max '(8 18 98 55 4 5 6)) (8 18 98 55 4 5 6) 但是如果我删除列表并写 (my-max 8 18 98 55 4 5 6) => 98,那么它就可以工作了。

我想了解如何编写适用于 () 的 max 函数,如果它为空,则它应该 return nil.

我尝试使用的功能

(defn my-max [x & xs]
  (cond (empty? xs) x
        (> (first xs) x) (recur (first xs) (rest xs))
        :else (recur x (rest xs))))
(require
        '[clojure.test :refer [is]])

(letfn [(my-max
            ([] nil)
            ([x] x)
            ([a b] (if (< a b) b a))
            ([a b & rest] (reduce my-max (conj rest a b))))]
    (is (= nil (my-max)))
    (is (= 1 (my-max 1)))
    (is (= 2 (my-max 1 2)))
    (is (= 3 (my-max 1 3 2)))
    (is (= 4 (my-max 4 1 3 2))))

您可以应用内置 max 或 akond 的回答中的函数:

(defn my-max [lst]
  (when (seq lst)
    (apply max lst)))

(my-max '(8 18 98 55 4 5 6))
=> 98
(my-max '())
=> nil

你也可以使用reduce:

(defn my-max [& args]
  (reduce #(if (< %1 %2) %2 %1) args))

reduceargs 中收集的第一个参数开始,并将其与 args 中的下一个元素进行比较。如果作为 %2 插入的下一个元素大于第一个元素 %1,则内部匿名函数的输出为 %2,否则为 %1。此输出在匿名函数的下一次调用中变为 %1,下一个元素变为 %2。因此,就好像内部函数总是将下一个元素与最近的最大元素进行比较,并为下一次比较保留两者中较大的一个。最后返回内部匿名函数的最后输出。

还有一个,只是为了好玩:

您可以为此雇用 max-key

(def my-max (partial apply max-key #(or % ##-Inf) nil))

user> (my-max [1 2 3])
;;=> 3

user> (my-max [])
;;=> nil

user> (my-max [1])
;;=> 1

user> (my-max [2 1])
;;=> 2