<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Clojure Q&amp;A - Recent questions tagged maps</title>
<link>https://ask.clojure.org/index.php/tag/maps</link>
<description></description>
<item>
<title>`merge-with` doesn´t treat pair (vectors of 2) the same way `merge` does</title>
<link>https://ask.clojure.org/index.php/14529/merge-with-doesnt-treat-pair-vectors-the-same-way-merge-does</link>
<description>&lt;pre&gt;&lt;code&gt;;; merge
(merge {:a :b} [:a :c]) ;=&amp;gt; {:a :c}

;; merge-with
(merge-with (fn [_ x] x) {} {:a :b} [:a :c])
;; =&amp;gt; class clojure.lang.Keyword cannot be cast to class java.util.Map$Entry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think this happens because &lt;code&gt;merge-with&lt;/code&gt; eventually &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L3090&quot;&gt;calls &lt;code&gt;seq&lt;/code&gt; on the &quot;Map&quot;&lt;/a&gt;, expecting to get a &quot;Map Entry&quot; from which then it can extracts &lt;code&gt;key&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt;, and fails when receiving a Vector, because &lt;code&gt;seq&lt;/code&gt; will just yield one element at a time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(key (first (seq {:a :c}))) ;; =&amp;gt; :a
(key (first (seq [:a :c])))
;; =&amp;gt; class clojure.lang.Keyword cannot be cast to class java.util.Map$Entry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think it is justified to expect that &lt;code&gt;(partial merge-with (fn [_ x] x))&lt;/code&gt; should behave exactly as &lt;code&gt;merge&lt;/code&gt; and my proposal is to make it happen, if what I described makes sense.&lt;/p&gt;
&lt;p&gt;Thank you!&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14529/merge-with-doesnt-treat-pair-vectors-the-same-way-merge-does</guid>
<pubDate>Thu, 01 May 2025 11:25:20 +0000</pubDate>
</item>
<item>
<title>Gather all keys and values of nested map that satisfies some condition</title>
<link>https://ask.clojure.org/index.php/14231/gather-all-keys-values-nested-that-satisfies-some-condition</link>
<description>&lt;p&gt;Hi,&lt;br&gt;
From a nested map, I'd like to build a map that saves all key - value pairs whose keys satisfy some conditions.&lt;br&gt;
I'm using babashka.&lt;br&gt;
Tried some different solutions, but I'm not able to retrieve all pairs.&lt;/p&gt;
&lt;p&gt;The first one, using (I think) a more functional approach &lt;code&gt;j-h5&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    #!/usr/bin/env bb
    
    ; expected output: {&quot;k23&quot; {&quot;k231&quot; &quot;v231&quot;} &quot;k24&quot; &quot;v24&quot;}
 (def j {&quot;k1&quot; &quot;v1&quot; &quot;k2&quot; {&quot;k21&quot; &quot;v21&quot; &quot;k22&quot; &quot;v22&quot; &quot;k23&quot; {&quot;k231&quot; &quot;v231&quot;} &quot;k24&quot; &quot;v24&quot;} &quot;k3&quot; &quot;v3&quot;})
(println j)

(println &quot;Doing j-h5&quot;)
(defn j-h5 [s mymap]
  (let [first-k (first (first s))
        first-v (second (first s)) ]
    (cond 
      (empty? s) nil
      (or (= &quot;k23&quot; first-k) (= &quot;k24&quot; first-k))
      (do 
        (assoc mymap first-k first-v)
        (when (and ( map? first-v) (seq first-v))
            (println  (str &quot;doing recursion1 when k:&quot; first-k &quot;  and v:&quot; first-v))
            (recur first-v mymap))
        )
      (map? first-v)
            (do 
              (println  (str &quot;doing recursion2 when k:&quot; first-k &quot;  and v:&quot; first-v))
              (recur first-v mymap))
      :else (recur (rest s) mymap) 
      )))

(j-h5 j {})
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;; mymap defined outside of function   
(println &quot;Doing j-h1&quot;)
(def  mymap {})
(defn j-h1 [s]
  (let [first-k (first (first s))
        first-v (second (first s)) ]
    (cond 
      (empty? s) mymap
      (or (= &quot;k23&quot; first-k) (= &quot;k24&quot; first-k))
      (do 
        (assoc mymap first-k first-v)
        (when (and ( map? first-v) (seq first-v))
            (println  (str &quot;doing recursion1 when k:&quot; first-k &quot;  and v:&quot; first-v))
            (recur first-v))
        )
      (map? first-v)
            (do 
              (println  (str &quot;doing recursion2 when k:&quot; first-k &quot;  and v:&quot; first-v))
              (recur first-v))
      :else (recur (rest s)) 
      )))

(j-h1 j)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How can this be fixed?&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14231/gather-all-keys-values-nested-that-satisfies-some-condition</guid>
<pubDate>Thu, 07 Nov 2024 21:38:20 +0000</pubDate>
</item>
<item>
<title>Apply two functions to a collection and to another that is a transformation of the other one</title>
<link>https://ask.clojure.org/index.php/14206/apply-functions-collection-another-transformation-other</link>
<description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;The challenge is to get the server name part of a collection of strings of fully qualified domain names.&lt;br&gt;
From: &lt;code&gt;[&quot;server1.oo.com&quot; &quot;s2.ee.com&quot;]&lt;/code&gt;&lt;br&gt;
To: &lt;code&gt;[&quot;server1&quot; &quot;s2&quot;] &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;I can do this to a single element as:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(subs &quot;server1.oo.com&quot; 0 (str/index-of &quot;server1.oo.com&quot; \.))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(subs &quot;server1.oo.com&quot; 0 (#(str/index-of % \.) &quot;server1.oo.com&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But nested &lt;code&gt;#()&lt;/code&gt; functions seem not to be possible.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(#(subs % 0 (#(str/index-of % \.) &quot;server1.oo.com&quot;)) &quot;server1.oo.com&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;returns an error.&lt;/p&gt;
&lt;p&gt;When using the collection, something like this works:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(let 
  [s-col [&quot;server1.oo.com&quot; &quot;s2.ee.com&quot;]]   
  (map #(subs % 0 5) s-col))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But, how can I use the &lt;code&gt;(str/index-of % \.)&lt;/code&gt; instead of that hard-coded &lt;code&gt;5&lt;/code&gt;?&lt;br&gt;
All my attempts were unsuccessful.&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14206/apply-functions-collection-another-transformation-other</guid>
<pubDate>Tue, 22 Oct 2024 22:13:46 +0000</pubDate>
</item>
<item>
<title>destructuring  corner case:  [&amp; {:as key-vals}]</title>
<link>https://ask.clojure.org/index.php/14005/destructuring-corner-case-as-key-vals</link>
<description>&lt;p&gt;I don't find the behavior of the following expression documented.&lt;br&gt;
Can someone either point me to the documentation, or I request&lt;br&gt;
that the documentation be updated to warn about this caveat.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/guides/destructuring&quot;&gt;https://clojure.org/guides/destructuring&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;((fn [&amp;amp; {:as key-vals}] key-vals) :a 100 :b 200) ;; case 1
(let [[&amp;amp; {:as key-vals}] '(:a 100 :b 200)] key-vals) ;; case 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These both evaluate to a map &lt;code&gt;{:a 100 :b 200)&lt;/code&gt;.  However, the following evaluate to &lt;code&gt;nil&lt;/code&gt; rather than an empty map.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;((fn [&amp;amp; {:as key-vals}] key-vals) ) ;; case 3
(let [[&amp;amp; {:as key-vals}] ()] key-vals)  ;; case 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The tag &lt;a rel=&quot;nofollow&quot; href=&quot;https://clojure.org/guides/destructuring#_keyword_arguments&quot;&gt;https://clojure.org/guides/destructuring#_keyword_arguments&lt;/a&gt; does not exactly say what happens in these cases; however, intuitively I'd expect that key-vals should be a map in all 4 cases.  Instead it is a map in the first to cases, but is &lt;code&gt;nil&lt;/code&gt; in cases 3 and 4.  I'd expect cases 3 and 4 to each evaluate to an empty map.&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/14005/destructuring-corner-case-as-key-vals</guid>
<pubDate>Wed, 03 Jul 2024 11:49:12 +0000</pubDate>
</item>
<item>
<title>Cheshire parse-string coerce keys to keywords</title>
<link>https://ask.clojure.org/index.php/13777/cheshire-parse-string-coerce-keys-to-keywords</link>
<description>&lt;p&gt;Just learning Clojure. I have the following json string:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def json &quot;{\&quot;a\&quot;: 1, \&quot;b\&quot;: \&quot;val\&quot;, \&quot;c\&quot;: {\&quot;D/E\&quot;: [1, 2, 3]}}}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the key-fn param is true in the Cheshire parse-string call I got the following map: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def parsed-json (cheshire/parse-string json true))
;; ==&amp;gt; {:a 1, :b &quot;val&quot;, :c #:D{:E [1 2 3]}}
(type parsed-json)
;; =&amp;gt; clojure.lang.PersistentArrayMap
(type (:c parsed-json))
;; =&amp;gt; clojure.lang.PersistentArrayMap
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How can I access the [1 2 3] array?  I don't understand what is #:D here, and how I can access :E.&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/13777/cheshire-parse-string-coerce-keys-to-keywords</guid>
<pubDate>Wed, 06 Mar 2024 18:06:15 +0000</pubDate>
</item>
<item>
<title>Run a task parallely to delete tags</title>
<link>https://ask.clojure.org/index.php/12999/run-a-task-parallely-to-delete-tags</link>
<description>&lt;pre&gt;&lt;code&gt;(defn- find-story-ids-by-tag [tag-id]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;  (map :id (db-content-tag/read-contents-by-tag-id (config/db-spec) tag-id)))&lt;/p&gt;
&lt;p&gt;(defn- update-story [txn publisher-id story-id tag-id]&lt;br&gt;
  (let [{:keys [published-json]} (db-content/find-by-id txn story-id)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    updated-tags (filter (fn [tag] (not= (:id tag) tag-id)) (:tags published-json))
    _ (db-story/update-published-json-without-timestamps txn publisher-id story-id (assoc published-json :tags updated-tags))]
(log/info {:message &quot;[TAG-DELETION] Updated Story Tags in Published JSON&quot;
           :publisher-id publisher-id
           :tag-id tag-id
           :story-id story-id
           :updated-tags-json updated-tags})))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(defn- delete-tag [publisher-id tag-id]&lt;br&gt;
  (let [associated-content-ids (find-story-ids-by-tag tag-id)]&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(transaction/with-transaction
  [txn (config/db-spec)]
  (do
    (when (seq associated-content-ids)
      (do
        (doseq [story-id associated-content-ids]
          (update-story txn publisher-id story-id tag-id))
        (db-content-tag/delete-batch-by-tag txn tag-id associated-content-ids)
        (log/info {:message &quot;[TAG-DELETION] Deleted from Content Tag&quot;
                   :publisher-id publisher-id
                   :tag-id tag-id
                   :story-ids associated-content-ids})))
    (db-tag/delete txn publisher-id tag-id)
    (log/info {:message &quot;[TAG-DELETION] Deleted Tag&quot;
               :publisher-id publisher-id
               :tag-id tag-id})))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(defn run [publisher-id tag-ids]&lt;br&gt;
  (comment run 123 [4 5 6])&lt;br&gt;
  (try&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(do
  (log/info {:message &quot;[TAG-DELETION] started&quot;
             :publisher-id publisher-id
             :tag-ids tag-ids})
  (doseq [tag-id tag-ids] (if (db-tag/find-by-id (config/db-spec) publisher-id tag-id)
                            (delete-tag publisher-id tag-id)
                            (log/info {:message &quot;[TAG-DELETION] Tag Not Found&quot;
                                       :publisher-id publisher-id
                                       :tag-id tag-id})))
  (log/info {:message &quot;[TAG-DELETION] completed&quot;
             :publisher-id publisher-id
             :tag-ids tag-ids}))
(catch Exception e
  (log/exception e {:message &quot;[TAG-DELETION] errored&quot;
                    :publisher-id publisher-id
                    :tag-ids tag-ids}))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If I have less than 100 tags this works, but say I have 100 000 tags it is very time consuming. How to modify this code which can run in parallel and takes less time? Currently the task uses seq for both deleting and updating the story&lt;/p&gt;
</description>
<category>Sequences</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12999/run-a-task-parallely-to-delete-tags</guid>
<pubDate>Sun, 04 Jun 2023 23:21:53 +0000</pubDate>
</item>
<item>
<title>filter with multiple lists on params</title>
<link>https://ask.clojure.org/index.php/12793/filter-with-multiple-lists-on-params</link>
<description>&lt;p&gt;Map, Filter and Reduce are very common in functional programming. &lt;br&gt;
Out of all languages that has those functions, only clojure has the capability to add multiple lists on map. for instance- (map + lst1 lst2) which is the most useful thing!&lt;/p&gt;
&lt;p&gt;But why isn't it possible to do the same with Filter? for example-&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(filter (fn [a1 b1] (pos? (+ a1 b1))) [1 2 3] [-2 4 0]) 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will result in &quot;Wrong number of args(3) passed to clojure.core/filter&quot;.&lt;br&gt;
I assume there is a reason for which it is not a common practice, but I find it hard to understand why.&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
</description>
<category>Macros</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12793/filter-with-multiple-lists-on-params</guid>
<pubDate>Wed, 22 Mar 2023 12:44:02 +0000</pubDate>
</item>
<item>
<title>submap? - recursively check if one map is contained in another</title>
<link>https://ask.clojure.org/index.php/12749/submap-recursively-check-if-one-map-is-contained-in-another</link>
<description>&lt;p&gt;&lt;code&gt;(submap? m1 m2)&lt;/code&gt; recursively checks if m1 is contained in m2&lt;/p&gt;
&lt;p&gt;Usage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(deftest submap
  (is (submap? {} {}))
  (is (not (submap? {:k 1} {})))
  (is (submap? {:k 1} {:k 1 :j 2}))
  (is (submap? {:k {:kk 1}} {:k {:kk 1 :j 2}}))
  (is (not (submap? {:k {:kk 1}} {:j 2}))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This need often arises in tests, where you want to check if the map returned by function-under-test has a certain shape and while assuming an open world - i.e. you want to ignore any additional keys so that changing function-under-test doesn't break the tests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;; BAD: doesn't assume open world
(is (= {:k :v} (function-under-test)))

;; BAD: not expressive
(is (= :v (:k (function-under-test))))

;; BAD: not expressive, need to write :k twice
(is (= {:k :v} (select-keys (function-under-test) [:k])))

;; GOOD: expressive
(is (submap? {:k :v} (function-under-test)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Implementations already exist in many codebases (400+ hits on Github code search). Examples:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/clojure/tools.deps/blob/ecc80420c1b734b384f7a42df91684cdbc37ddc6/src/test/clojure/clojure/tools/deps/util.clj#LL12-L25C18&quot;&gt;https://github.com/clojure/tools.deps/blob/ecc80420c1b734b384f7a42df91684cdbc37ddc6/src/test/clojure/clojure/tools/deps/util.clj#LL12-L25C18&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ptaoussanis/encore/blob/96547700c03a5e81d784bcc9253980d7355f2f2b/src/taoensso/encore.cljc#L2071&quot;&gt;https://github.com/ptaoussanis/encore/blob/96547700c03a5e81d784bcc9253980d7355f2f2b/src/taoensso/encore.cljc#L2071&lt;/a&gt;&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12749/submap-recursively-check-if-one-map-is-contained-in-another</guid>
<pubDate>Thu, 09 Mar 2023 19:24:33 +0000</pubDate>
</item>
<item>
<title>Addition/Multiplication operations on loop</title>
<link>https://ask.clojure.org/index.php/12466/addition-multiplication-operations-on-loop</link>
<description>&lt;p&gt;Hi! &lt;br&gt;
It's me again. I followed up on the previous answers that have been posted on my questions to do another operation but I don't get exactly what I want. &lt;br&gt;
Here's the situation:&lt;/p&gt;
&lt;p&gt;My first table (products) looks like : (product_name price)&lt;br&gt;
([1 (candies 6.5)]
[2 (sweets 1.75)]&lt;br&gt;
[3 (jam 2.99)]
[4 (gum 1.25)])&lt;/p&gt;
&lt;p&gt;My first table (products) looks like : (customer_name product_name quantity)&lt;br&gt;
([1 (Sara candies 3)]
[2 (Joe jam 3)]&lt;br&gt;
[3 (Sara gum 1)])&lt;/p&gt;
&lt;p&gt;What I'm trying to do is if i type for example Sara, I'll get the sum of the sales made by Sara, which means: (3&lt;em&gt;6.5 + 1&lt;/em&gt;1.25) = $20.75 (in this case)&lt;/p&gt;
&lt;p&gt;I'm fine for the input part (I get the name of the customer as an input from the terminal)&lt;br&gt;
However, my code:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn sales_prices_with_cond [name_cus] (map
 (fn [y z]
   (if (= (str name_cus) (str (nth (first z) 1)))
   list (* (Double. (nth (second y) 1)) (Integer/parseInt (nth (second z) 2))))
   )
products 
sales))
(println (reduce + sales_prices_with_cond &quot;Sara&quot;))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gives me the sum of ALL the sales*quantities. It's like the condition is skipped or maybe not well written ...&lt;br&gt;
I also tried with (some) and got the same result...&lt;/p&gt;
&lt;p&gt;Please Help :') .&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12466/addition-multiplication-operations-on-loop</guid>
<pubDate>Sat, 10 Dec 2022 05:55:32 +0000</pubDate>
</item>
<item>
<title>Map destructuring works on singleton lists</title>
<link>https://ask.clojure.org/index.php/12374/map-destructuring-works-on-singleton-lists</link>
<description>&lt;p&gt;(let [{x :x} '({:x &quot;foo&quot;})]  x)&lt;br&gt;
;; =&amp;gt; &quot;foo&quot;&lt;/p&gt;
</description>
<category>ClojureScript</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/12374/map-destructuring-works-on-singleton-lists</guid>
<pubDate>Thu, 10 Nov 2022 08:15:43 +0000</pubDate>
</item>
<item>
<title>Cast to Map$Entry Exception When Trying to (Into {}) After Sequence Operations</title>
<link>https://ask.clojure.org/index.php/11879/cast-mapentry-exception-trying-after-sequence-operations</link>
<description>&lt;p&gt;Is it intended behavior to get this exception  :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;class clojure.lang.Keyword cannot be cast to class java.util.Map$Entry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;on this piece of code :&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(def a [[&quot;Active&quot; :Transit-RLC &quot;Active&quot;]])

(-&amp;gt;&amp;gt; a
     (transduce
       (comp 
             (map drop-last)
             (map reverse))
       conj [])
     (into {}))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;changing the transducer to &lt;code&gt;(map (-&amp;gt; [(second %) (first %)])&lt;/code&gt; solves the issue.&lt;br&gt;
Thanks&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11879/cast-mapentry-exception-trying-after-sequence-operations</guid>
<pubDate>Sun, 08 May 2022 09:17:12 +0000</pubDate>
</item>
<item>
<title>Common patterns for optional fields interact poorly with spec</title>
<link>https://ask.clojure.org/index.php/11584/common-patterns-optional-fields-interact-poorly-with-spec</link>
<description>&lt;p&gt;I do lots of work with spec, and a frequent problem that I run into is in constructing a spec'ed object that is a map with optional fields.&lt;/p&gt;
&lt;p&gt;A &lt;a rel=&quot;nofollow&quot; href=&quot;https://grep.app/search?q=assoc%28.%2A%5Cn%29%7B0%2C5%7D.%2A%3A.%2A%5C%28®exp=true&amp;amp;filter[lang][0]=Clojure&quot;&gt;common pattern&lt;/a&gt; looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(assoc {::required-field :value}
       ::optional-field (when some-condition
                          :optional-value))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a significant issue with this pattern however: if &lt;code&gt;::optional-field&lt;/code&gt; is on a &lt;code&gt;spec/keys&lt;/code&gt; &lt;code&gt;:opt&lt;/code&gt; field that is non-nilable, then every object that excludes the optional field will be invalid according to that spec because it will have a &lt;code&gt;nil&lt;/code&gt; value instead of omitting the key.&lt;/p&gt;
&lt;p&gt;The alternative to this approach is to use something like &lt;code&gt;cond-&amp;gt;&lt;/code&gt; as seen below:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(cond-&amp;gt; {::required-field :value}
  some-condition (assoc ::optional-field :optional-value))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This pattern is far from the only usage of &lt;code&gt;cond-&amp;gt;&lt;/code&gt;, but it &lt;a rel=&quot;nofollow&quot; href=&quot;https://grep.app/search?q=%5C%28cond-%3E%28.%2A%5Cn%29%7B1%2C3%7D.%2A%5C%28assoc%5Cs®exp=true&amp;amp;filter[lang][0]=Clojure&quot;&gt;appears fairly frequently&lt;/a&gt;. I see this pattern as detrimental because it requires the condition to be surfaced all the way at the top here, and there cannot be a way for some function used to produce &lt;code&gt;:optional-value&lt;/code&gt; to abort via nil punning while still producing a valid value without requiring additional flow control and local bindings.&lt;/p&gt;
&lt;p&gt;A more flexible solution to this problem uses &lt;code&gt;if-some&lt;/code&gt;, but this solution is verbose and becomes unwieldy when multiple optional fields need to be included at once, as can be seen below.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(let [m {::required-field :value}
      m (if-some [v (produces-optional-value)]
          (assoc m ::optional-field v)
          m)
      m (if-some [v (produces-other-value)]
          (assoc m ::other-field v)
          m)]
  m)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One solution to this problem is the function &lt;code&gt;assoc-some&lt;/code&gt;, which is like &lt;code&gt;assoc&lt;/code&gt;, but when given a &lt;code&gt;nil&lt;/code&gt; value it elides the key. This function is provided in &lt;a rel=&quot;nofollow&quot; href=&quot;http://weavejester.github.io/medley/medley.core.html#var-assoc-some&quot;&gt;medley&lt;/a&gt;, and &lt;a rel=&quot;nofollow&quot; href=&quot;https://grep.app/search?q=assoc-some&amp;amp;filter[lang][0]=Clojure&quot;&gt;sees some use&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The above unwieldy example would, with &lt;code&gt;assoc-some&lt;/code&gt;, look like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(assoc-some {::required-field :value}
            ::optional-field (produces-optional-value)
            ::other-field (produces-other-value))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is likely not the only solution to this problem, but I think it is a problem worth considering.&lt;/p&gt;
&lt;p&gt;An example of another instance where the named solution &lt;em&gt;wouldn't&lt;/em&gt; work, but that appears to follow more or less the same pattern is &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/IGJoshua/farolero/blob/950d81e4a417770dd9d51b67358dbb2cc89b2cc2/src/cljc/farolero/core.cljc#L503-L516&quot;&gt;this code in farolero&lt;/a&gt;, which would be solved by a parallel function (that I have not yet found an implementation of in the wild besides my own) &lt;code&gt;update-some&lt;/code&gt; which will update a key with a new value, and if that value is &lt;code&gt;nil&lt;/code&gt; will remove the key.&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/11584/common-patterns-optional-fields-interact-poorly-with-spec</guid>
<pubDate>Tue, 15 Feb 2022 21:48:34 +0000</pubDate>
</item>
<item>
<title>Can js/BigInt be used as a map key in ClojureScript?</title>
<link>https://ask.clojure.org/index.php/10938/can-js-bigint-be-used-as-a-map-key-in-clojurescript</link>
<description>&lt;p&gt;js/BigInt supports equality testing (= (js/BigInt 4) (js/BigInt 4)) is true so I expected to be able to use it as a key in a map (I don't know what hash function is used for the lookup)&lt;br&gt;
However I see some unexpected behaviour:&lt;/p&gt;
&lt;p&gt;&lt;code&gt; (get {0 0 1 1 2 2 3 3 (js/BigInt 4) 4 5 5 7 7 8 8} (js/BigInt 4))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;returns &lt;code&gt;4&lt;/code&gt; as expected, but&lt;/p&gt;
&lt;p&gt;&lt;code&gt; (get {0 0 1 1 2 2 3 3 (js/BigInt 4) 4 5 5 7 7 8 8 9 9} (js/BigInt 4))&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;returns &lt;code&gt;nil&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This was tested using Firefox or Safari as the javascript engine. &lt;/p&gt;
&lt;p&gt;Is this a bug or was I just lucky that it worked for maps with less than 10 entries?&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
</description>
<category>ClojureScript</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10938/can-js-bigint-be-used-as-a-map-key-in-clojurescript</guid>
<pubDate>Fri, 13 Aug 2021 02:19:31 +0000</pubDate>
</item>
<item>
<title>No metadata on clojure 1.9 map literals</title>
<link>https://ask.clojure.org/index.php/10724/no-metadata-on-clojure-1-9-map-literals</link>
<description>&lt;p&gt;Maps written using the new &lt;code&gt;#:default.namespace{,,,}&lt;/code&gt; syntax don't get file positions attached as metadata.&lt;/p&gt;
&lt;p&gt;Given this setup code&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(require '[clojure.tools.reader :as reader])
(require '[clojure.tools.reader.reader-types :as reader-types])

(defn sample [s]
  (with-open [r (java.io.StringReader. s)]
    (meta (reader/read (reader-types/indexing-push-back-reader (reader-types/push-back-reader r) 1)))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;this edn literal fails to get parsed with positional metadata&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(sample &quot;#:ns{ :key :val }&quot;) ; =&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;unlike those two, which get their positional metadata as expected&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(sample &quot;{ :key :val }&quot;)     ; =&amp;gt; {:line 1, :column 1, :end-line 1, :end-column 14}
(sample &quot;{ :ns/key val }&quot;)   ; =&amp;gt; {:line 1, :column 1, :end-line 1, :end-column 16}
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>tools.reader</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/10724/no-metadata-on-clojure-1-9-map-literals</guid>
<pubDate>Wed, 23 Jun 2021 07:40:15 +0000</pubDate>
</item>
<item>
<title>How do I update map elements conditionally?</title>
<link>https://ask.clojure.org/index.php/9477/how-do-i-update-map-elements-conditionally</link>
<description>&lt;p&gt;I have some code that's massaging a data structure from one format to another (SVG hiccup attributes to CLJFX attributes). The format are quite similar but when an attribute is present I need to occasionally futz with it a bit. For instance, maybe I need to (read-string ..) a string into a number, or update a keyword so it's spelled a bit different, etc.&lt;/p&gt;
&lt;p&gt;Right now my code is of the form&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(-&amp;gt; svg-attributes
  (update :stroke #(case %
                     nil :black
                     &quot;none&quot; :black
                     (if (= \# %)
                       %
                       (keyword %))))
  (update :fill #(case %
                   nil &quot;transparent&quot;
                   &quot;none&quot; &quot;transparent&quot;
                   (if (= \# %)
                     %
                     (keyword %))))
  (update :points #(case %
                     nil []
                     [] []
                     (map read-string (-&amp;gt; %
                                          (clojure.string/split #&quot;[ ,]&quot;)))))
  (update :stroke-width #(case %
                           nil 1.0
                           %))
  (update :stroke-dasharray #(case %
                               nil []
                               (map read-string (-&amp;gt; %
                                                    (clojure.string/split #&quot;[ ,]&quot;)))))
  (clojure.set/rename-keys {:stroke-dasharray :stroke-dash-array})
  (update :font-size #(case %
                        nil 10
                        &quot;none&quot; 10
                        %))))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The issue is that I keep having to catch the &lt;code&gt;nil&lt;/code&gt; case and jamming in some defaults... which works most of the time.. but  I'd rather skip updating when there is nothing to update.&lt;/p&gt;
&lt;p&gt;I saw this question, which is quite similar: &lt;a rel=&quot;nofollow&quot; href=&quot;https://ask.clojure.org/index.php/8387/how-to-avoid-nil-values-in-maps&quot;&gt;https://ask.clojure.org/index.php/8387/how-to-avoid-nil-values-in-maps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Is the idiomatic solution to do a &lt;code&gt;(cond-&amp;gt; &lt;/code&gt; with a &lt;code&gt;(some? (:somekeyword %))&lt;/code&gt; on each line ? I feel like I'm not reaching for the right tool here! Maybe someone can give me a better suggestion :)&lt;/p&gt;
</description>
<category>Collections</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9477/how-do-i-update-map-elements-conditionally</guid>
<pubDate>Mon, 20 Jul 2020 05:59:14 +0000</pubDate>
</item>
<item>
<title>Is there a better way to create random groups out of multiple collections of different sizes?</title>
<link>https://ask.clojure.org/index.php/9333/better-create-random-groups-multiple-collections-different</link>
<description>&lt;p&gt;I am writing a slack bot that can take a group of people and the office that they work for and then break them into n random groups, making sure to mix the two offices together.&lt;/p&gt;
&lt;p&gt;I have a few functions that do this just fine, but I am wondering if there is a more &quot;Clojure&quot; way to do this? I am still trying to break out of my object-oriented habits so any suggestions are very welcome.&lt;/p&gt;
&lt;p&gt;My thought for this approach was to treat this like a deck of cards and deal the people out into each resulting group until I run out of people in an office, then move to the next one until I run out of offices then return my result.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defn split 
  &quot;split by office then shuffle
   result is sorted by size&quot;
  [coll]
  (-&amp;gt;&amp;gt; (sort-by :office coll)
       (partition-by :office)
       (sort-by count)
       (map shuffle)))

(defn conj-in 
  &quot;inserts an item into a collection's child&quot;
  [coll idx itm]
    (assoc coll idx (conj (nth coll idx) itm)))

(defn split-into-groups
  [coll]
  (let [sorted (split coll)]
    (loop [pool    (rest sorted)
           hand    (first sorted)
           result  (into [] (take @ngroups (repeat [])))
           idx     0]
      
      (if (not-empty hand)
        (let [next (first hand)]
          (recur pool
                 (rest hand)
                 (conj-in result idx next)
                 (mod (inc idx) @ngroups)))
        
        (if (not-empty pool)
          (recur (rest pool)
                 (first pool)
                 result
                 idx)
          
          result)))))
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9333/better-create-random-groups-multiple-collections-different</guid>
<pubDate>Thu, 28 May 2020 19:49:37 +0000</pubDate>
</item>
<item>
<title>is there a version of pr-str that emit full versions of qualified keywords in maps instead of short forms?</title>
<link>https://ask.clojure.org/index.php/9222/there-version-versions-qualified-keywords-instead-short-forms</link>
<description>&lt;p&gt; Something like &lt;code&gt;{:foo/bar 1}&lt;/code&gt; instead of &lt;code&gt;#:foo{:bar 1}&lt;/code&gt;&lt;br&gt;
I need to debug some edn and it's impossible to jump to the desired keywords if they're in the short forms.&lt;/p&gt;
</description>
<category>Syntax and reader</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9222/there-version-versions-qualified-keywords-instead-short-forms</guid>
<pubDate>Fri, 10 Apr 2020 07:54:25 +0000</pubDate>
</item>
<item>
<title>What is keywords for clj used for? What do they actually mean and do?</title>
<link>https://ask.clojure.org/index.php/9192/what-is-keywords-for-clj-used-for-what-they-actually-mean-and</link>
<description>&lt;p&gt;I learned about keywords a while back, but Im not sure what they are actually used for outside of for keys in maps. Are there other uses for keywords outside of maps?&lt;/p&gt;
&lt;p&gt;Also what do they actually mean and do?&lt;/p&gt;
</description>
<category>Clojure</category>
<guid isPermaLink="true">https://ask.clojure.org/index.php/9192/what-is-keywords-for-clj-used-for-what-they-actually-mean-and</guid>
<pubDate>Fri, 27 Mar 2020 09:04:53 +0000</pubDate>
</item>
</channel>
</rss>