This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-07
Channels
- # announcements (11)
- # babashka (29)
- # beginners (70)
- # biff (13)
- # calva (1)
- # clojure (24)
- # clojure-europe (125)
- # clojure-nl (1)
- # clojure-norway (7)
- # clojure-portugal (2)
- # clojure-uk (3)
- # clojurescript (9)
- # core-async (29)
- # cursive (4)
- # emacs (10)
- # etaoin (14)
- # events (3)
- # fulcro (10)
- # funcool (4)
- # helix (1)
- # honeysql (12)
- # introduce-yourself (1)
- # jobs (2)
- # juxt (2)
- # lsp (1)
- # off-topic (17)
- # polylith (58)
- # portal (20)
- # remote-jobs (2)
- # shadow-cljs (2)
- # squint (4)
- # tools-deps (9)
Question, how can I update 2 values at least at once in a map? For example, I do this where I tae the date and apply a function where it returns "time-ago" like instead of date, returns "5 days ago":
(map #(update % :created_at (constantly (time-ago (:created_at %)))) @data-combined)
I wanna do the same for :updated_at, for instance:
(map #(update % :updated_at (constantly (time-ago (:updated_at %)))) @data-combined)
How can I do both at the same time?Given that both those calls to update
use a constantly
function, you can just use assoc
with two kv pairs.
And you can always combine multiple calls to update
or any other functions with e.g. ->
.
And the constantly
function is not needed in this case because it is created newly on each iteration. So a (map (-> (update :created_at time-ago) (update :updated_at time-ago)) @data-combined)
should be fine
Almost. Gotta turn that ->
into a function. Either with #(...)
and %
or with (fn [...] ...)
.
And yeah, I didn't notice that the same field was passed to time-ago
so consequent application of update
makes more sense than a single assoc
.
Right! Thatnks. assoc worked for both, and now I changed it to this also and works too:
(map #(-> % (update :created_at time-ago) (update :updated_at time-ago)) @data-combined)
Can I also add a new key based on some condition in the map? Like a new key for each called :type ?
You can do anything with a combination of assoc
/`update`/`dissoc`.
There's also cond->
that might be useful. And condp
. And many, many other things.
remember that the thing passed to map is a full function, so you're allowed to use things like if
, let
, and other constructs like that within them.
I've got a library that's giving me a Java JsonStructure (https://www.oracle.com/technical-resources/articles/java/json.html) - is there an existing JsonStructure -> clojure wrapper?
If you need a more performance, it's a few lines of code to parse into Clojure's data structures:
(defprotocol Parseable
(parsed [x]))
(extend-protocol Parseable
JsonArray
(parsed [x]
(into [] (map parsed x)))
JsonObject
(parsed [x]
(into {} (map (fn [[k v]] [k (parsed v)]) x)))
JsonNumber
(parsed [x]
(if (.isIntegral x)
(.longValue x)
(.doubleValue x)))
JsonString
(parsed [x]
(.getString x))
JsonValue
(parsed [x]
(case x
JsonValue/TRUE true
JsonValue/FALSE false
JsonValue/NULL nil)))
(with-open [reader (Json/createReader (io/reader (io/resource "test.json")))]
(parsed (.read reader)))
This worked great, though for some reason I couldn't extend the protocol to the JsonStructure interfaces, I had to extend to the classes that implement them. But that's fine, I don't need the flexibility. 👍
You can also use destructuring:
(let [{:keys [id]} peer]
{:id id})
clojure.core
even 🙂