wrongusername
wrongusername

Reputation: 18918

Finding the position of an object in a sequence in Clojure

Essentially, I want a function that works like this:

user=> (pos 'c '(a b c d e f g) =)
2
user=> (pos 'z '(a b c d e f g) =)
nil

And I came up with this:

(defn pos
  "Gets position of first object in a sequence that satisfies match"
  [object sequence match]
  (loop [aseq sequence position 0]
    (cond (match object (first aseq)) position
          (empty? aseq) nil
          :else (recur (rest aseq) (inc position)))))

So my question is, is there some built-in function that would allow us to do this, or would there be a better, more functional/Clojure-ish way to write the pos function?

Upvotes: 2

Views: 1280

Answers (1)

amalloy
amalloy

Reputation: 92147

Well, if you really want to look for a particular item you can use .indexOf on the collection; if you're looking to do something more general with predicates you don't need a function and an item, just a function is plenty.

(defn pos [pred coll]
  (->> coll
       (map-indexed #(when (pred %2) %1))
       (remove nil?)
       (first)))

user> (pos #{'c} '(a b c d e f g))
2

On the other hand, there's a reason this isn't included in clojure.core: it's not very efficient, and you very rarely care about indices in a collection - if you do, you should usually rethink your algorithm.

Upvotes: 6

Related Questions