This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-01-05
Channels
- # announcements (1)
- # babashka (61)
- # babashka-sci-dev (1)
- # beginners (54)
- # biff (17)
- # cider (4)
- # circleci (1)
- # clj-commons (39)
- # clj-kondo (26)
- # cljdoc (40)
- # clojure (41)
- # clojure-europe (32)
- # clojure-norway (4)
- # clojure-portugal (1)
- # clojure-uk (2)
- # clojurescript (59)
- # clr (69)
- # conjure (7)
- # cursive (22)
- # data-science (16)
- # datalevin (1)
- # datomic (19)
- # docker (31)
- # funcool (1)
- # honeysql (6)
- # hoplon (1)
- # hyperfiddle (41)
- # introduce-yourself (1)
- # juxt (2)
- # leiningen (5)
- # nbb (14)
- # nextjournal (38)
- # off-topic (47)
- # polylith (2)
- # rdf (5)
- # re-frame (4)
- # reitit (27)
- # releases (6)
- # scittle (10)
- # shadow-cljs (24)
- # sql (11)
- # squint (1)
- # tools-build (33)
- # tree-sitter (4)
- # vim (39)
what is the standard solution to render clojure API json response with ring
? ring-json
lib?
I've the following dependency graph:
(def dependency-graph {:n3 #{:n1 :n2}
:n4 #{:n3}})
Each element in the set is a direct dependency of a node (the map key). How would I invert this data structure in a functional way so it describes the required-by relationship instead of the depends-on relationship?
I've tried something like this, but I would need to additionally merge all the maps at each reduce step:
(reduce {} (fn [inverted [node dependencies]]
(for [dep dependencies]
(if (contains? inverted dep)
(let [required-by (get inverted dep)]
(assoc inverted dep (conj required-by node)))
(assoc inverted dep #{node})))) graph)
Is there an elegant solution to this?(reduce-kv
(fn [acc par deps]
(reduce #(update %1 %2 (fnil conj #{}) par) acc deps))
{}
graph)
This looks a lot cleaner 🙂. Thanks @U04HK53G7SQ
(def x {:foo 1, :bar -3}) (def y {:foo 1, :bar -3}) (identical? x y) returns false
(def a 1)
(def b 1)
Why (identical? a b) - returns true ?
Because the maps are not identical objects in memory. Check out https://clojuredocs.org/clojure.core/identical_q and read the comments, especially the last one about being careful about using the function at all
It's JVM semantics, you can come up with much simpler cases, like (identical? 0.0 .0.0) => false
I have seen code in the clojure core that make use with-meta
when do we need to use with-meta in our application ?
when you have to add metadata to some dynamically created object that supports metadata.
user=> (meta (let [x [1 2 3]] ^:foo x))
nil
user=> (meta (let [x [1 2 3]] (with-meta x {:foo true})))
{:foo true}
the first line here might look like you add metadata to the object but in fact it adds metadata to the var #'x that doe not exists outside of let expressionthere are few cases when it can be usefull here is one for example https://clojure.org/reference/protocols#_extend_via_metadata
by adding metadata you can implement a protocol implicitly
Metadata is also useful for cases where you want to be able to compare data using =
while attaching certain metadata to the data, e.g. :source
. The data stays equivalent, but you get to keep track of where it came from.
This returns true, for example:
(= (with-meta {:a 1} {:source "$some_user"})
(with-meta {:a 1} {:source "$some_other_user"}))
Can I ask for some advice please, as I've hit a brick wall in my understanding? I'm sure this has been asked before but I can't find an answer that I fully understand. I have an array of maps that is originally derived from a json file. I'm trying to perform a substring search on one of the keys in each map and create a new array of maps with all the full map entries that return true. e.g [{:title "the quick brown fox" :data "data" :more "data"} {:title "the slow brown fox" :data "data2" :more "data2"} ] (into [] (filter (string/includes? (:title map) "quick") data) would return [{:title "the quick brown fox" :data "data" :more "data"}] However, after a mixed bag of various attempts at using filter I either get empty arrays, arrays with true or false values or errors. Are there any useful links or documentation that might point me in the right direction? Thanks!
I'm not sure if it's a typo or part of your problem, but you're not passing a function to filter
, you're passing the boolean result of calling a function
If you care about the result being a vector and not a lazy seq, you could call
(let [foo [{:title "the quick brown fox"
:data "data"
:more "data"}
{:title "the slow brown fox"
:data "data2"
:more "data2"}]]
(filterv #(str/includes? (:title %) "quick") foo))
Just filter
would return a lazy seq.Edited. I’d elided the extraction of the :title
.
@U2EJEK2SX if you want to paste a gist or something I can try to help
A way to think about this so you can get yourself unstuck in the future. When you want to do something to a collection, write a function that works on a single one. And only once that function is working on a single one then use it with filter and the rest of the functions
Meta-tip: I know well the temptation, but I try never to post anything other than actual code. People are going to spend time on analyzing and even running it, I figure, so it has to be real. No harm I guess in loudly announcing the code is just pseudo-code up front. hth!
Demonstration of @U11BV7MTK’s suggestion. Break it down to extremely easy problems, and build back up to the target.
Thanks @U90R0EPHA that's a really helpful example
I could do with some help, I have the following data structure
(let [c {1 [1 2 3 4 5]
2 [1 2 3 4 5]
3 [6 7 8 9 10]
4 [1 4 5 6 7]}]
And values a
and b
.
What I'd like to do is remove all keys from c
that are less than a
, and when the key is equal to a
, remove all values from that key which are less than b
.
e.g.
(let [c {1 [1 2 3 4 5]
2 [1 2 3 4 5]
3 [6 7 8 9 10]
4 [1 4 5 6 7]}
a 3
b 7]
Would give
{3 [7 8 9 10]
4 [1 4 5 6 7]}
What I've tried to get working:
(-> (into {} (remove (fn [[k _]] (< k a)) c))
(assoc a (remove (fn [[_ v]] (< v b))(c a))))
But I'm getting the error
; TypeError: n.replace is not a function
and no idea why!This works, but I'm thinking there must be a nicer way
(into {} (for [[k v] c
:when (>= k a)]
[k (if (= k a)
(remove (fn [x] (< x b)) v) v)]))
Have you considered using a https://clojuredocs.org/clojure.core/sorted-map
`(subseq (into (sorted-map) {1 [1 2 3 4 5] 2 [1 2 3 4 5] 3 [6 7 8 9 10] 4 [1 4 5 6 7]}) < n)`
❯ clj -Sdeps '{:deps {org.clojure/data.avl {:mvn/version "0.1.0"}}}'
Downloading: org/clojure/data.avl/0.1.0/data.avl-0.1.0.pom from central
Downloading: org/clojure/data.avl/0.1.0/data.avl-0.1.0.jar from central
Clojure 1.11.1
user=> (require '[clojure.data.avl :as avl])
nil
user=> (let [c (avl/sorted-map
1 [1 2 3 4 5]
2 [1 2 3 4 5]
3 [6 7 8 9 10]
4 [1 4 5 6 7])
a 3
b 7]
(avl/subrange c >= a <= b))
{3 [6 7 8 9 10], 4 [1 4 5 6 7]}
user=>
Is their any specific reason why I was getting the error n.replace is not a function
with my code ?
I'm finding clojure(script) errors pretty tricky to deal with and find the actual problem
for the rest i'd go w/ something like (as-> thing m (into (sorted-map) m) (update m a (partial filter (partial >= b)) (subseq m < n) (into {} m))
or whatever
avl trees offer a non-linear way to accomplish this. just wanted to highlight that. ie no filter on the keys yourself
on the error, you're trying to destructure members of (c a)
into [_ v]
, but it's a flat vector
oh yeah! I was confused thinking I was still dealing with key value pairs at that point.
How is it possible this works? pluss function arity is 2
(defn pluss [x y]
(Integer/sum x y))
(reduce pluss [1]) => 1
(doc reduce)
"If coll has only 1 item, it is returned and f is not called."
yes, thank you!