.toUpperCase
I recently learnt that when you want to convert the case of a technical identifier (a tagname, a HTTP header etc.) you must not use plain .toUpperCase
or .toLowerCase
but specify Locale/ENGLISH
.
I recently learnt that when you want to convert the case of a technical identifier (a tagname, a HTTP header etc.) you must not use plain .toUpperCase
or .toLowerCase
but specify Locale/ENGLISH
.
(merge-with + {:a 12} {:b 4} {:a 3 :b 7})
return?{:b 11, :a 15}
when there are several values for a key, these values are merged (two at a time) using the specified function — here they are summed.merge-with
?(apply merge-with + (map (fn [x] {x 1}) coll))
or, using for
: (apply merge-with + (for [x coll] {x 1}))
.(select (html-resource (java.net.URL. "http://clojure-log.n01se.net/")) [:#main [:a (attr? :href)]])
returns a seq of link nodes.
One asked me how to count occurrences of each value in a collection. I answered (reduce #(assoc %1 %2 (inc (%1 %2 0))) {} coll)
. Since it can take some time to get accustomed to the functional way of thought, here is how one can work such an expression out:
(count (filter #{42} coll))
reduce
?(defn my-count [coll] (reduce (fn [n _] (inc n)) 0 coll))
reduce
?(reduce (fn [n _] (inc n)) 0 (filter #{42} coll))
filter
?(reduce (fn [n x] (if (= 42 x) (inc n) n)) 0 coll)
{42 occurences-count}
.(reduce (fn [m x] (if (= 42 x) (assoc m 42 (inc (m 42))) m)) {42 0} coll)
(reduce (fn [m x] (if (= 42 x) (assoc m x (inc (m x))) m)) {42 0} coll)
{42 0}
with {}
?(inc (m x))
would fail because (m x)
would return nil
.(a-map a-key default-value)
{42 0}
with {}
?(reduce (fn [m x] (if (= 42 x) (assoc m x (inc (m x 0))) m)) {} coll)
(reduce (fn [m x] (assoc m x (inc (m x 0)))) {} coll)
or, terser, (reduce #(assoc %1 %2 (inc (%1 %2 0))) {} coll)
Exercise:
(merge-with + {:a 12} {:b 4} {:a 3 :b 7})
return?merge-with
?(do (defmacro foobar [x] (doto x println)) (foobar (+ 1 1)))
?
foobar
is treated as a function (its argument has been evaluated) because foobar
is unknown before the whole top-level expression is compiled.foobar
preexists and is a macro, (foobar (+ 1 1))
is expanded.This behaviour bit me while using with-test
to test macros. It’s the kind of bug that goes unnoticed while developing incrementally and evaluating in the same REPL, it was waiting for me to start a fresh REPL.
net.cgrand.enlive-html=> (sniptest "<div id=user-data>"
[:#user-data] (html-content "code injection<script>alert('boo')</script>")
[:#user-data (but #{:p :br :a :strong :em})] nil)
"<html><body><div id=\"user-data\">code injection</div></body></html>"
You also need to remove most attributes but it’s just a demo of something that was impossible with the old Enlive.
By the way, the old Enlive is no more. Long live the new Enlive!
Make it work, make it right, make it fast.
See the README file to know what’s new and here for an example.
I wanted to apply a function to every second item in a coll. I was considering writing something using interleave
, take-nth
and map
or a combination of mapcat
and partition
when I thought of this:
(map #(%1 %2) (cycle [f identity]) coll)
I really love clojure’s map parallel processing. (I should ask if every?
and some
could be allowed to take several colls.)