Created
August 10, 2010 19:33
-
-
Save ihodes/517833 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; want this behavior | |
(defn iof | |
[val coll] | |
(lazy-seq | |
(loop [coll coll idx 0] | |
(cond | |
(empty? coll) '() | |
(= val (first coll)) (cons idx (recur val (rest coll) (inc idx))) | |
:else (recur val (rest coll) (inc idx)))))) | |
;; works, but kind of ugly | |
(defn iof-2 | |
[val coll] | |
((fn f [coll idx] | |
(lazy-seq (cond | |
(empty? coll) '() | |
(= val (first coll)) (cons idx (f (rest coll) (inc idx))) | |
:else (f (rest coll) (inc idx))))) coll 0)) | |
;; idiomatic? (also could do arity overloading, but this is to keep from exposing the private API) | |
(defn- -indices-of | |
[val coll idx] | |
(lazy-seq | |
(cond | |
(empty? coll) '() | |
(= val (first coll)) (cons idx (-indices-of val (rest coll) (inc idx))) | |
:else (-indices-of val (rest coll) (inc idx))))) | |
(defn indices-of | |
"Returns a lazy-seq of indices where 'val appears in 'coll." | |
[val coll] (-indices-of val coll 0)) |
One way to do it:
user> (defn indices-of [x xs] (filter identity (map-indexed #(when (= x %2) %1) xs)))
#'user/indices-of
user> (indices-of 'foo '[foo bar baz foo])
(0 3)
Totally forgot about map-indexed–that would be the most natural way to do this. Thanks! Regardless, I'm curious about the way to do this if map-indexed didn't exist.
Variation on the same theme then:
(defn indices-of [x xs]
(let [f (fn f [idx y ys]
(lazy-seq
(when (seq ys)
(cons (and (= y (first ys)) idx)
(f (inc idx) y (rest ys))))))]
(filter identity (f 0 x xs))))
user> (indices-of 'foo '[bar foo bar foo bar])
(1 3)
Ah, interesting. Similar to my iof-2
, but with a clarifying let
block.
Perhaps the below would be idiomatic? I'm averse to using more seq xs
then necessary, if empty?
works.
(defn iof-2
[val coll]
(letfn [(f [coll idx]
(lazy-seq (cond
(empty? coll) '()
(= val (first coll)) (cons idx (f (rest coll) (inc idx)))
:else (f (rest coll) (inc idx)))))
(f col 0)))
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NB: I realize the first one doesn't work. I think it looks the nicest, though.