Reputation: 18918
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
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