There are many options for this. Here are a few:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test)
(:require
[clojure.string :as str]
[tupelo.core :as t]
))
(def numbers [:one :two :three :four :five])
(def colors [:green :red :blue :pink :yellow])
(def letters [:A :B :C :D :E])
(verify
; The tupelo.core/indexed function will add a 0-based index to each element in a sequence
(is= (t/indexed [:a :b :c])
[[0 :a]
[1 :b]
[2 :c]]))
The tupelo.core/indexed function will add a 0-based index to each element in a sequence, which is often handy.
(verify
; tupelo.core/map-let allows you to assign a local name to each item from multiple sequences
; but behaves like `map`, not `for`
(let [vecs (t/map-let [n numbers
c colors
l letters]
[n c l]) ; return a vector containing each item in sequence
]
(is= vecs
[[:one :green :A]
[:two :red :B]
[:three :blue :C]
[:four :pink :D]
[:five :yellow :E]])))
Using t/map-let allows you to give a local name to the elements of each sequence, but does not create the cartesian product like with for.
(verify
(t/let-spy-pretty ; or just `let` to suppress the "spy" printing
[
; using (mapv vector ...) will also place each triple into a vector
vecs (mapv vector numbers colors letters)
strs (mapv #(str/join " - " %) vecs)
strs-idx (t/indexed strs)
lines (t/forv [[the-idx the-str] strs-idx]
(str the-idx ": " the-str))]
(is= vecs
[[:one :green :A]
[:two :red :B]
[:three :blue :C]
[:four :pink :D]
[:five :yellow :E]])
(is= strs
[":one - :green - :A"
":two - :red - :B"
":three - :blue - :C"
":four - :pink - :D"
":five - :yellow - :E"])
(is= strs-idx
[[0 ":one - :green - :A"]
[1 ":two - :red - :B"]
[2 ":three - :blue - :C"]
[3 ":four - :pink - :D"]
[4 ":five - :yellow - :E"]])
(is= lines
["0: :one - :green - :A"
"1: :two - :red - :B"
"2: :three - :blue - :C"
"3: :four - :pink - :D"
"4: :five - :yellow - :E"])))