# 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à!
{"ft_lang_label":"__label__en","ft_lang_prob":0.79772085,"math_prob":0.8761658,"size":2521,"snap":"2023-40-2023-50","text_gpt3_token_len":832,"char_repetition_ratio":0.19110052,"word_repetition_ratio":0.03816794,"special_character_ratio":0.38714796,"punctuation_ratio":0.135255,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9874885,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2023-09-23T11:37:41Z\",\"WARC-Record-ID\":\"<urn:uuid:d6f0989c-1e44-43f1-ac6c-cf37a4d1aa54>\",\"Content-Length\":\"89755\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:bab42136-d067-4584-b2a6-b8b327858845>\",\"WARC-Concurrent-To\":\"<urn:uuid:eaf742e7-0470-483e-85fe-6acb8af41411>\",\"WARC-IP-Address\":\"104.21.12.9\",\"WARC-Target-URI\":\"https://isaacsu.com/2014/02/lists-into-tuples/\",\"WARC-Payload-Digest\":\"sha1:D3V7KXRI4WCANLABXWTUNNI226XZB7WZ\",\"WARC-Block-Digest\":\"sha1:F4OJ5UEACEEL7J4P5SRPNZK3DQY6CYVI\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2023/CC-MAIN-2023-40/CC-MAIN-2023-40_segments_1695233506480.7_warc_CC-MAIN-20230923094750-20230923124750-00535.warc.gz\"}"}