# Combining lists into tuples

Here’s how you can zip up multiple lists into a single list of pairs or tuples using `(map vector )`.

```(def letters [:a :b :c])
(def numbers [1 2 3])
(def fruits ["peach" "tomato" "orange"])

(map vector letters numbers)
; => ([:a 1] [:b 2] [:c 3])

(map vector letters fruits numbers)
; => ([:a "peach" 1] [:b "tomato" 2] [:c "orange" 3])
```

Cool trick, but how is this useful, you ask?

Say we’ve got 3 sales reps:

```(def sales-reps ["Alice" "Bob" "Carl"])
```

and 8 states/territories in Australia to cover:

```(def au-states ["ACT" "NSW" "NT" "Qld" "SA" "Tas" "Vic" "WA"])
```

We don’t really care who’s assigned where, as long as each state has someone assigned to it.

```(map vector sales-reps au-states)
; => (["Alice" "ACT"] ["Bob" "NSW"] ["Carl" "NT"])
```

Almost. You see, `(map )` bombs out as soon as any of the lists runs out (in our case `sales-reps`).

We’ll need to enlist the help of `(cycle )`.

```(cycle sales-reps)
; => ("Alice" "Bob" "Carl" "Alice" "Bob" "Carl" "Alice" ...)

(take 4 (cycle sales-reps))
; => ("Alice" "Bob" "Carl" "Alice")
```

Let’s try again:

```(def assignments
(map vector (cycle sales-reps) au-states))
; => (["Alice" "ACT"] ["Bob" "NSW"] ["Carl" "NT"] ["Alice" "QLD"]
;     ["Bob" "SA"] ["Carl" "TAS"] ["Alice" "VIC"] ["Bob" "WA"])
```

Nice. This time, `(cycle )` returns an infinitely cycling list, so `(map )` stops when `au-states` runs out.

So which states were assigned to `Alice`?

```(defn is-alice? [tuple] (= (first tuple) "Alice"))

(def alice-tuples
(filter is-alice? assignments))
; => (["Alice" "ACT"] ["Alice" "Qld"] ["Alice" "Vic"])

(defn just-states [tuple] (second tuple))

(map just-states alice-tuples)
; => ("ACT" "Qld" "Vic")
```

See all the states grouped by their respective sales reps:

```(def grouped-by-reps (group-by first assignments))
; => {"Alice" [["Alice" "ACT"] ["Alice" "Qld"] ["Alice" "Vic"]],
;     "Bob"   [["Bob" "NSW"] ["Bob" "SA"] ["Bob" "WA"]],
;     "Carl"  [["Carl" "NT"] ["Carl" "Tas"]]}
```

Clean it up a little:

```(map (fn [assignment]
[(first assignment) (map just-states (second assignment))])
grouped-by-reps)

; => (["Alice" ("ACT" "Qld" "Vic")]
;     ["Bob"   ("NSW" "SA" "WA")]
;     ["Carl"  ("NT" "Tas")])
```

With this last one, we’re mapping over `grouped-by-reps`, each `assignment` looks like this:

```["Bob" [["Bob" "NSW"] ["Bob" "SA"] ["Bob" "WA"]]]
```

Breaking it down:

```(first assignment)  ; =>  "Bob"
(second assignment) ; => [["Bob" "NSW"] ["Bob" "SA"] ["Bob" "WA"]]
(map just-states (second assignment)) ; => ("ACT" "Qld" "Vic")

; Hence
[(first assignment) (map just-states (second assignment))]
; => ["Bob" ("ACT" "Qld" "Vic")]
```

Voilà!