Getting index of char from end

746 views
Skip to first unread message

jongwon.choi

unread,
Nov 11, 2011, 5:36:05 PM11/11/11
to Clojure
Hi

I'm wondering the best way to express:

(position #\a "abba" :from-end t)

Should I use interop?

(.lastIndexOf "abba" (int \a))

Thanks!

Jestan Nirojan

unread,
Nov 12, 2011, 2:07:24 AM11/12/11
to Clojure
I think regex free solution is best for this

(defn last-indexof [s c]
(->> s (filter #(= c %)) count dec)

Jestan Nirojan

unread,
Nov 12, 2011, 12:53:32 PM11/12/11
to Clojure
My solution is very wrong, sorry for that.

I am just wondering, cant we use memfn to make lastIndexOf as a first
class function here?

areduce can be used too.

(defn last-indexof [cs c]
(areduce cs i lst-idx -1
(if (= c (aget cs i)) i lst-idx)))

(-> "aabbccd" to-array (last-indexof \c))

Regards.
Jestan Nirojan

Ulises

unread,
Nov 12, 2011, 5:54:10 PM11/12/11
to clo...@googlegroups.com
Here's my take on it (all caveats apply, e.g. performance):

(defn indices-of
"Returns the indices of the given char in the string (0 based)."
[c string]
(map second (filter #(= c (first %)) (partition 2 (interleave string
(iterate inc 0))))))

(indices-of \a "abba") ; (0 3)

and hence last-index-of becomes:

(def last-index-of (comp last indices-of))
(last-index-of \a "abbaa") ; 4

U

Tyler Perkins

unread,
Nov 12, 2011, 6:49:46 PM11/12/11
to Clojure
Interesting. I never knew how to use areduce before. However, it
always scans the entire array. If you had a very long string (or other
collection), it might be better to scan backwards:

user> (defn last-indexof [cs c]
(loop [n (dec (count cs))]
(if (and (<= 0 n) (not= c (nth cs n)))
(recur (dec n))
n)))
#'user/last-indexof
user> (last-indexof "aabbccd" \c)
5
user> (last-indexof "aabbccd" \x)
-1

Andreas Kostler

unread,
Nov 13, 2011, 3:54:36 AM11/13/11
to clo...@googlegroups.com
How about using the clojure sequence functions?
(require '[clojure.contrib.seq-utils :as seq-utils])

(defn last-index-of [c string]
(first (seq-utils/find-first (fn [[_ a]] (= a c)) (reverse
(seq-utils/indexed string)))))

P.S. Jong Won, how are you liking Clojure? I've met you in Parramatta
and joined the ADO team :) Nice to have you on the group here :)

Cheers
Andreas

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

Andreas Kostler

unread,
Nov 13, 2011, 3:55:28 AM11/13/11
to Clojure
How about using the clojure sequence functions?
(require '[clojure.contrib.seq-utils :as seq-utils])
(defn last-index-of [c string]
(first (seq-utils/find-first (fn [[_ a]] (= a c)) (reverse
(seq-utils/indexed string)))))
P.S. Jong Won, how are you liking Clojure? I've met you in Parramatta
and joined the ADO team :) Nice to have you on the group here :)
Cheers
Andreas

On Nov 13, 6:54 pm, Andreas Kostler <andreas.koest...@leica-

jongwon.choi

unread,
Nov 13, 2011, 4:02:59 PM11/13/11
to Clojure
Andreas, how're you doing? Frankly my impression of Clojure is just
like this posting.

You know usually with Common Lisp my common sense works - it provides
more than I expect. With Clojure I have to double check because my
expectation is more than Clojure provides, mostly.

And it ends up being using Java side - which might be more than I
expect in a harsh way! (It is like doing assembly programming in C)

I believe Clojure is great for Java programmers but not sure for
Common Lisp programmers. But it is definitely an interesting toy! (I'm
writing a toy web framework in Clojure to see how far I can go)

Hope you're doing well!
(PS: You shouldn't put such code into ADO production code! :-)

On Nov 13, 7:55 pm, Andreas Kostler <andreas.koestler.le...@gmail.com>
Reply all
Reply to author
Forward
0 new messages