Изменение функции count для возврата нуля для строк и нуля для чисел

Я пишу функцию, которая может вводить строки, числа, массивы, коллекции Java и карты. Ограничения - это вывод для обеих строк, а числа должны быть равны нулю.

Счетчик функции Clojure делает все, что мне нужно, за исключением ограничений. Таким образом, я решил использовать оператор if для проверки, является ли ввод строкой или числом. Возврат нуля, если тест истинен, и использовать счетчик в противном случае. У меня есть работоспособный код для любого случая, но не знаю, как объединить два. Более того, я не уверен, что самый эффективный способ настроить тестирование в этом случае.

(defn Swanson [a]
 (if (string? a) 0
 (count a)))

 (defn Propello [b]
 (if (instance? Number b) 0
 (count b)))
4 ответа

Если ясность важнее эффективности (и это почти всегда есть), я бы использовал cond здесь:

(cond
 (string? a) 0
 (instance? Number a) 0
 :default (count a))

Там есть вероятность, что то, что вы действительно хотите, это "подсчет, если он счет, иначе 0". В этом случае функция "seq" может помочь

(if (seq a) (count a) 0)

И если вы действительно заботитесь о производительности, делать это с помощью протоколов, вы должны купить в принципе больше оптимизаций JVM. Но профиль до и после, чтобы убедиться!

(defprotocol SwansonPropello
 (swanson-propello [a]))

(extend-protocol SwansonPropello
 clojure.lang.ISeq
 (swanson-propello [a] (count a))

 clojure.lang.Seqable
 (swanson-propello [a] (count a))

 Object
 (swanson-propello [_] 0))


Другой вариант:

(defn swanson-propello [x]
 (if (or (string? x)
 (number? x))
 0
 (count x)))

or является самой фундаментальной формой для такого типа комбинирования. Его докштрина хорошо описывает это:

Evaluates exprs one at a time, from left to right. If a form
returns a logical true value, or returns that value and doesn't
evaluate any of the other expressions, otherwise it returns the
value of the last expression. (or) returns nil.


(defn alex
 [obj]
 (cond
 (string? obj) 0
 (number? obj) 0
 :otherwise (count obj)))


#(if (string? %)
 0
 (count %))

licensed under cc by-sa 3.0 with attribution.