Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure sub-sequence position in sequence

Does Clojure provide any builtin way to find the position of a sub-sequence in a given sequence?

like image 987
Tudor Vintilescu Avatar asked Mar 05 '13 12:03

Tudor Vintilescu


2 Answers

Clojure provides a builtin way for easy Java Interop.

(java.util.Collections/indexOfSubList '(a b c 5 6 :foo g h) '(5 6 :foo))
;=> 3
like image 144
A. Webb Avatar answered Nov 18 '22 23:11

A. Webb


A sequence is an abstraction, not a concretion. Certain concretions that you can use through the sequence abstraction have a way to find the position of a subsequence (strings and java collections, for instance), but sequences in general don't, because the underlying concretion doesn't have to have an index.

What you can do however, is create a juxt of the element identity and an index function. Have a look at map-indexed.

Here's a naive implementation that will lazily find the position of (all) the subsequence(s) in a sequence. Just use first or take 1 to find only one:

(defn find-pos
  [sq sub]
  (->>
    (partition (count sub) 1 sq)
    (map-indexed vector)
    (filter #(= (second %) sub))
    (map first)))

=> (find-pos  [:a :b \c 5 6 :foo \g :h]
                [\c 5 6 :foo])
(2)

=> (find-pos  "the quick brown fox"
                (seq "quick"))
(4)

Take care that index-based algorithms generally aren't something you would do in a functional language. Unless there are good reasons you need the index in the final result, lavish use of index lookup is considered code smell.

like image 28
NielsK Avatar answered Nov 18 '22 23:11

NielsK