This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-13
Channels
- # admin-announcements (1)
- # announcements (40)
- # aws (2)
- # babashka (46)
- # babashka-sci-dev (106)
- # beginners (31)
- # cider (5)
- # circleci (2)
- # clj-kondo (48)
- # clojure (118)
- # clojure-belgium (1)
- # clojure-chicago (3)
- # clojure-europe (19)
- # clojure-ireland (3)
- # clojure-losangeles (2)
- # clojure-nl (2)
- # clojure-spec (10)
- # clojure-uk (4)
- # clojurescript (18)
- # community-development (5)
- # core-async (159)
- # cursive (16)
- # datomic (16)
- # etaoin (1)
- # fulcro (21)
- # funcool (14)
- # graalvm (5)
- # gratitude (4)
- # holy-lambda (28)
- # jobs (1)
- # jobs-discuss (1)
- # kaocha (1)
- # lsp (12)
- # malli (21)
- # meander (12)
- # music (1)
- # off-topic (8)
- # portal (5)
- # react (18)
- # reitit (1)
- # releases (4)
- # remote-jobs (1)
- # shadow-cljs (56)
- # timbre (4)
Hi all, I started to play around with Clojure and I love itΒ π, looking for some help/direction in the following: I have the following sequence and want to get all the :id values from it (including the nested maps):
({:id "A123",
:x ({:id "B123", :name "a", :y ()})}
{:id "A454",
:x ({:id "B546",
:y ({:id "C888", :name "b"}
{:id "C999", :name "b"}
{:id "C444", :name "b"})}
{:id "B774",
:y ({:id "C123", :name "b"})})})
I want to get
("A123" "B123" "A454" "B546" "C888" "C999" "C444" "B774" "C123")
I got to the solution using map, flatten, and keep but wanted to see if someone thinks of a better/cleaner way of doing it :)> I got to the solution using map, flatten, and keep but wanted to see if someone thinks of a better/cleaner way of doing it π Mind sharing your solution?
tree-seq to the rescue (thanks @UK0810AQ2):
(->>
(tree-seq map?
(fn [m]
(concat (:x m)
(:y m)))
(quote {:id "A454",
:x ({:id "B546",
:y ({:id "C888", :name "b"}
{:id "C999", :name "b"}
{:id "C444", :name "b"})}
{:id "B774",
:y ({:id "C123", :name "b"})})}))
(map :id))
;; => ("A454" "B546" "C888" "C999" "C444" "B774" "C123")
Works when called on a node. You have a toplevel sequence, so you'll either have to create a fake toplevel node {:x (...
and remove nils afterwards, or do the toplevel step manually.(defn go
[o]
(cond
(string? o) [o]
(sequential? o) (->Eduction (mapcat go) o)
(map? o)
(let [{:keys [id x y]} o]
(->Eduction (mapcat go) [id x y]))))
This is great, really appreciate your help! There is a lot to learn from these solutions, it will take some time to fully understand them but I think it's an excellent starting point. @U3X7174KS My solution was wrong but I was doing something like this, it didn't look right at all
(defn go
[inventory]
(->> inventory
(map :x)
flatten
(keep :y)
flatten
(keep :id)))
I often find that flatten is a code smell. Don't think I came across a case where it should have been used, yet. Whenever you're doing something recursive (walks are recursive), start from your terminals and build up
You don't necessarily have to get it right the first time, either. In my implementation I forgot to cat in the sequential case, but it's easy to see in the output
literally all we need here is "recursively, if it has an :id
key, then the val for that key", and tree-seq makes that easy
99% of the time, if I am using tree-seq, the first two args are coll?
and seq
Is there something like jet
but with YAML support?
:rolling_on_the_floor_laughing: why jet then?
oh! I didn't know that.
Has anyone leveraged carmine the redis client within the context of stuart sierra's component framework? I'm wondering what a component that contains a redis connection pool might look like.
I have something like
(defrecord Redis [redis-spec datasource]
component/Lifecycle
(start [component]
(if datasource
component
(let [redis (assoc component :datasource redis-spec)]
(car/wcar (:datasource redis)
(car/ping))
redis)))
(stop [component]
(assoc component :datasource nil)))
at the moment, but I am not sure how the wcar method manages this thread pool. The redis spec I provide has a :pool {}
which is stored under :datasource
in my record and is used in the start method's usage of car/wcar
. Iam not sure how to keep this thread pool "open". The docs I've seen so far all interact with redis through the wcar macro which apparently should leverage the same thread pool, but I am not understanding how this works or is kept open. Is my :datasource map being modified by the macro?if I recall, rather annoyingly, carmine doesn't let you manage connection objects, but instead keeps its own global reference to them
so your car/ping will start up the connection, and the carmine library will keep it open
https://github.com/ptaoussanis/carmine/blob/master/src/taoensso/carmine/connections.clj#L173-L199
I wrote a custom connection pool thing using jedis directly at work. jedis comes with some kind of built in connection pool, we had some requirements around handling long running pub/sub connections I wasn't sure it met
Thanks. I was about to ask if it was possible to manage my own connection then pass that to carmine somehow. That is what I am doing with my database following sean corfield's web app example with a pooled postgres connection
We've gone through a number of Redis solutions along the way, discarding several for various reasons, before settling on basic Jedis plus our own connection pooling code. We did use Carmine at one point before switching to Redisson but I no longer remember what my issues were with Carmine (certainly it managing its state in globals internally would have been one of the things that I decided we couldn't live with).
Redisson is bloatware (and was very slow to provide JDK compatibility post Java 8, as I recall) -- we shaved 10-15MB off our JAR files by dropping Redisson I think?
I used to be quite a fan of "fancy" Clojure wrappers for Java libraries but over the years I've switched to being more a fan of just using an industry-tested Java library with some interop π