Created
April 11, 2018 04:35
-
-
Save jjttjj/926b60731ffd87e6556ec5cc47d8cc61 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
(defn zipmap+ | |
"Like zipmap, except `tags` can contain the following: | |
keywords: treated like zipmap | |
A vector with a boolean value for it's first element: | |
the boolean dictates weather the rest of the values in the vector should put | |
into the parent map and processed. | |
A vector containing a function f followed by a single keyword k: | |
The value at this point is parsed as an integer X, and the function applied to | |
it, to result in integer Y. Y items are collected from the input vals in a sequence | |
and assoc'ed with keyword k in the resulting map" | |
[keys vals] | |
(loop [result {} | |
tags (seq keys) | |
vs (seq vals)] | |
(if (and tags vs) | |
(let [tag (first tags) | |
v (first vs)] | |
(cond | |
(keyword? tag) (recur (assoc result tag (first vs)) | |
(next tags) | |
(next vs)) | |
;;include? | |
(and (vector? tag) (true? (first tag))) | |
(recur result | |
(concat (next tag) (next tags)) | |
vs) | |
;;exclude? | |
(and (vector? tag) (false? (first tag))) | |
(recur result (next tags) vs) | |
(and (vector? tag) (fn? (first tag))) | |
(let [f (first tag) | |
n (f (Long/parseLong v)) | |
[taken remaining] ((juxt take drop) n (rest vs))] | |
(recur (assoc result (second tag) taken) | |
(next tags) | |
remaining)) | |
:else (throw (ex-info "unrecognized input" | |
{:tag tag :value v})))) | |
result))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment