0

I'm writing a function that can input strings, numbers, arrays, Java Collections and Maps. The constraints are the output for both strings and numbers should be zero.

The Clojure function count does everything I need, except handle the constraints. So, I thought to use an if statement to test if the input is a string or a number. Returning zero if the test is true, and using count otherwise. I have workable code for either case, but do not know how to combine the two. Moreover, I am not sure the most efficient way to set up the testing in this case.

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

  (defn Propello [b]
        (if (instance? Number b) 0
        (count b)))
sunspots
  • 1,047
  • 13
  • 29

4 Answers4

1

Another option:

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

or is the most fundamental form for this type of combining. Its docstring describes it well:

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.
jbm
  • 2,575
  • 16
  • 15
1

If clarity is more important than efficiency (and it almost always is), then I'd use cond here:

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

There's the possibility that what you really want is "the count if it's countable, otherwise 0". In that case, the 'seq' function can help

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

And if you actually care about performance, doing it with protocols should let you buy into more JVM optimizations in principle. But profile before and after to make sure!

(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))
Russell Mull
  • 1,151
  • 8
  • 15
  • I realized that strings are seqable, so the second two examples won't solve your specific problem. cond is the way to go. – Russell Mull Nov 07 '13 at 07:50
0
#(if (string? %)
   0
   (count %))
noisesmith
  • 20,076
  • 2
  • 41
  • 49
0
(defn alex
  [obj]
  (cond
    (string? obj) 0
    (number? obj) 0
    :otherwise (count obj)))
Leon Grapenthin
  • 9,246
  • 24
  • 37