如何在 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))
reduce
从 args
中收集的第一个参数开始,并将其与 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
几天前我对 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))
reduce
从 args
中收集的第一个参数开始,并将其与 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