Reputation: 17650
*Simple question : Why does this function throw an exception when evaluated ? *
In the case where there is a duplicate in the string , there is a Class cast exception thrown upon finding the duplicate.
In the case where the string has no duplicates, a NullPointerException is thrown.
*The Code *
(defn first-duplicate-char [str-in]
(loop [list-Rem (seq str-in) set-Seen (set [])]
(print (type list-Rem) " " list-Rem (next list-Rem) "\n")
(if (= 0 (count str-in))
nil
(if (some #(= (first list-Rem) %) set-Seen)
(first list-Rem)
(recur
(seq (next list-Rem))
(conj set-Seen (first list-Rem)))))))
Upvotes: 1
Views: 212
Reputation: 2831
Your problem is that (= 0 (count str-in))
never changes, so you eventually try to call first
on nil
. [EDIT: I'm wrong, your code actually works as is -- that if statement is just a no-op. I hope you enjoy the rest of this answer anyway.]
Instead, you should be calling next
(not rest
) on list-Rem
in the recur
and using list-Rem
directly in the if
test, using the property of next
that returns nil for an empty seq. Here's how I would rewrite your code:
(defn first-duplicate [in]
(loop [seen #{}
remain (seq in)]
(when-let [[head & tail] remain]
(if (contains? seen head)
head
(recur (conj seen head) tail)))))
Changes:
seq
on the output of next
or rest
contains?
(check for existence of key) is faster than some
(run a predicate on elements until something yields a truthy value)when
to return nil
on test failurewhen-let
to destructure and bind first char and restStylistic changes:
Upvotes: 2