Reputation: 771
I am fairly new to Clojure and would help help with some code. I have a function which takes a vector and i would like to loop through the vector and get the value at an index 'i' and the value of 'i' itself. 'i' is the value which is incremented in the loop.
I have checked 'for' at the clojure docs at for and wrote the following code.
(for [i some-vector]
(print (get-intersec i (.length some-vector) loop-count)))
The loop-count variable is supposed to be the loop count.
I have also checked loop but it does not seem like a feasible solution. Can someone help me with a clojure function i can use or help me write a macro or function that can do that.
Thank you.
Ps: To solve my problem, i use my own counter but would like a better solution.
Upvotes: 0
Views: 2004
Reputation: 29958
Don't forget dotimes
for simple stuff like this:
(let [data [:a :b :c :d]]
(dotimes [i (count data)]
(println i " -> " (data i))
; or (nth data i)
; or (get data i)
))
with result
0 -> :a
1 -> :b
2 -> :c
3 -> :d
Using loop/recur would look like this:
(let [data [:a :b :c :d]]
(loop [i 0
items data]
(let [curr (first items)]
(when curr
(println i "->" curr)
(recur (inc i) (rest items))))))
Update:
If you need this a lot, I already wrote a function that will add the index value to the beginning of each entry in a sequence:
(ns tst.demo.core
(:use tupelo.test)
(:require [tupelo.core :as t]) )
(dotest
(let [data [:a :b :c :d]]
(t/spy-pretty :indexed-data
(t/indexed data))))
with result
:indexed-data =>
([0 :a]
[1 :b]
[2 :c]
[3 :d])
The general signature is:
(indexed & colls)
Given one or more collections, returns a sequence of indexed tuples
from the collections like:
(indexed xs ys zs) -> [ [0 x0 y0 z0]
[1 x1 y1 z1]
[2 x2 y2 z2]
... ]
Upvotes: 3
Reputation: 4235
If your not set on using for, you could use map-indexed
e.g.
(map-indexed (fn [i v]
(get-intersect v (.length some-vector) i))
some-vector))
I don't know what get-intersect
is and assume .length
is java interop? Anyway, map-indexed
expects a function of 2 arguments, the 1st is the index and the second is the value.
Upvotes: 1
Reputation: 10865
First, keep in mind that for
is for list comprehension, that is, creating new sequences. For looping through a sequence for some side effect, like printing, you probably want to use doseq
.
To include a numeric count with each element as you loop through, you can use map-indexed
:
(def xs [:a :b :c :d])
(doseq [[n elem] (map-indexed #(vector %1 %2) xs)]
(println n "->" elem))
Output:
0 -> :a
1 -> :b
2 -> :c
3 -> :d
If you find yourself doing this a lot, like I did, you can create a macro:
(defmacro doseq-indexed [[[item idx] coll] & forms]
`(doseq [[~idx ~item] (map-indexed #(vector %1 %2) ~coll)]
~@forms))
And use it like this:
> (doseq-indexed [[n elem] xs] (println n "->" elem))
0 -> :a
1 -> :b
2 -> :c
3 -> :d
Upvotes: 6