Welcome! Please see the About page for a little more info on how this works.

+2 votes
in Clojure by
edited by

Maybe clojure core could consider a function:

(defn index-of [coll elt] ...)

This would help in cases where you currently have to write:

(.indexOf something :foo)
which is a big ugly since you need to know something about the implementation of e.g. PersistenVectors or other types.

The index-of function could work for clojure.lang.Indexed, java.util.List and java.lang.String instances and maybe this could be extended further with a protocol.

I realize index-of is not an ideal function to use with regards to performance, but it has its use cases.

Should this function be generalized into one that returns a (lazy) seq of indexes instead of only the first?

1 Answer

0 votes

clojure.string/index-of exists for the string case. For colls, similar tickets have been considered and declined in the past (https://clojure.atlassian.net/browse/CLJ-2056 is the one in my head, but I think there may be others).

> Use of linear search (and in particular nested linear search) leads to poor performance

Yes, I get that, yet I see people using `.indexOf` interop which bugged me a little, since this relies on internals.
To bring a slightly other dimension into this thread -- Back in 2010, a Clojure contributor replied in the Google Group,

"It's not in core to promote better suited data types (sets, maps) because 95% of the time .indexOf is used to check if an element is in a collection (if it's a one-off you can use (some #(= item %) coll))."
My angle is standardization: I don't like to support `.indexOf` on vectors in babashka, since that exposes implementation details, so it would be nice to have a core function for this, or indeed, recommend the `some` approach.
The "`some` approach" will tell you if something is a member of the collection, but it won't tell you the index (basically, it's asking, does the predicate return true for something in the collection, and returns true/nil appropriately). But that doesn't tell you where something is in the collection. Several times I've wanted an `index-of` function in core covering all sequential collections (anything that would respond to `nth`). I typically use this for statistical types of routines, where I want to say that a given data value represents such and such a percentile. So, sort the collection, find the element index, divide index by count of elements, etc. Yes, it has linear time bounds. That hasn't stopped `clojure.string/index-of` from being useful. Yes, it would be better for programs to implement binary search, particularly for sorted data. That would be useful in core as well (vectors only).