Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure: map function isn't returning something I can eval

I'm writing a little "secret santa" program to get my hands dirty with Clojure, and I'm stumbling with my output.

The program takes a list of sets (Santas), extracts their emails into another list, then randomly assigns recipients to Santas. I think I've mostly got it, but when I try to output the results of my map, I'm getting #<Fn@dc32d15 clojure.core/map$fn__4549>,

(ns secret-santas-helper.core
  (:require [clojure.pprint :as pprint])
  (:gen-class))

(def santas [{:name "Foo" :email "[email protected]"}
             {:name "Bar" :email "[email protected]"}
             {:name "Baz" :email "[email protected]"}])

(defn pluck
  "Pull out the value of a given key from a seq"
  [arr k]
  (map #(get % k) arr))

(defn find-first
  "Find the first matching value"
  [f coll]
  (first (filter f coll)))

(defn assign-santas
  "Iterate over a list of santas and assign a recipient"
  [recipients santas]
  (let [r (atom recipients)])
  (map (fn [santa]
          (let [recipient (find-first #(= % (get santa :email)) @recipients)]
            (assoc santa :recipient recipient)
            (swap! recipients (remove #(= % recipient) recipients))))))

(defn -main []
  (let [recipients (shuffle (pluck santas :email))
        pairs (assign-santas recipients santas)]
      (pprint/pprint pairs)))
like image 908
Kevin Whitaker Avatar asked Dec 05 '25 00:12

Kevin Whitaker


1 Answers

Also be careful on how you use map. You are returning the result of your swap! which I don't believe is what you are aiming at.

Keep working on getting your version compiling and functioning correctly. I wanted to give an alternative solution to your problem that works less with mutation and instead is focused on combining collections.

(def rand-santas
  "Randomize the current santa list"
  (shuffle santas))

(def paired-santas
  "Use partition with overlap to pair up all random santas"
  (partition 2 1 rand-santas))

(def final-pairs
  "Add the first in the list as santa to the last to ensure everyone is paired"
  (conj paired-santas (list (last rand-santas) (first rand-santas))))

(defn inject-santas 
  "Loop through all pairs and assoc the second pair into first as the secret santa"
  [pairs]
  (map 
    (fn [[recipent santa]]
      (assoc recipent :santa santa))
    pairs))

(defn -main [] 
  (pprint/pprint (inject-santas final-pairs)))
like image 61
rabidpraxis Avatar answered Dec 07 '25 23:12

rabidpraxis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!