To start let's define the following
user=>(defn sort-map [m] (apply sorted-map (apply concat m)))
That's right. A function to cast hash-map to tree-maps.
user=>(sort-map {3 :a 1 :c 2 :b})
{1 :c, 2 :b, 3 :a}
Why would I do that? Because I now have a way of making subsets based on the keys.
user=>(keys-pred take-while #(< 2 %) (sort-map {3 :a 1 :c 2 :b}))
{1 :c}
user=>(keys-pred drop-while #(< 2 %) (sort-map {3 :a 1 :c 2 :b}))
{2 :b, 3 :a}
So, when would this have an application?

Let's define the following map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;Defined in terms of pennies to avoid float error | |
(def xkcd | |
(sorted-map-by | |
(comp - compare) | |
215 :fruit | |
275 :fries | |
335 :salad | |
355 :wings | |
420 :cheeze | |
580 :sampler)) | |
;Assume seq-utils is used | |
(defn order | |
([amt menu] (distinct (flatten (vector (order amt menu {}))))) | |
([amt menu items] | |
(let [affordable (keys-pred drop-while #(< amt %) menu) | |
exact-entry? (affordable amt)] | |
(cond | |
(empty? affordable) {} | |
exact-entry? (merge-with + items {exact-entry? 1}) | |
true | |
(remove empty? | |
(set | |
(map | |
#(let [next-amt (- amt (key %)) | |
next-items (merge-with + items {(val %) 1})] | |
(order next-amt affordable next-items)) | |
affordable))))))) | |
user=>(order 1505 xkcd) | |
({:fruit 1, :wings 2, :sampler 1} {:fruit 7}) |
And there you go, a use for take/drop while with maps :)
No comments:
Post a Comment