This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-08-20
Channels
- # announcements (3)
- # beginners (63)
- # calva (1)
- # cider (24)
- # clj-kondo (98)
- # cljdoc (8)
- # cljsrn (19)
- # clojure (106)
- # clojure-conj (2)
- # clojure-europe (5)
- # clojure-italy (5)
- # clojure-nl (8)
- # clojure-spec (8)
- # clojure-uk (13)
- # clojuredesign-podcast (7)
- # clojurescript (54)
- # core-async (1)
- # cursive (3)
- # data-science (1)
- # datomic (19)
- # fulcro (7)
- # hoplon (1)
- # off-topic (3)
- # re-frame (13)
- # reitit (1)
- # shadow-cljs (234)
- # test-check (10)
- # tools-deps (59)
- # unrepl (1)
- # yada (20)
I am trying to merge vector of maps.
I tried doing it using the reduce
method but unable to retrieve the expected result.
Input data:
(def data ([{:padding-top "30px"} {:padding-top "40px"} {:padding-top "50px"}] [{:margin "40px"}]))
(defn merge-data
[data]
)
Expected Output:
(merge-data data)
({:padding-top "30px" :margin "40px"}
{:padding-top "40px"}
{:padding-top "50px"})
The input data is a list of two vectors, each of which contains maps.
yes that’s correct. coming from JS background I am just thinking using something like forEach. But I am trying to figure out how to do it in more functional way.
So you have two vectors of maps, we can call the first vector's elements [a1 a2 a3 ...] and the second vector's elements [b1 b2 b3 ...], and these two vectors might have different numbers of maps in them.
You want to return a single list or vector of maps which contain [(merge a1 b1) (merge a2 b2) (merge a3 b3) ...], and if one vector runs out of maps before the other one, just return those maps?
that’s absolutely right
there is one more problem the vector elements can be more. [a1, a2, a3…], [b1, b2, b3], [c1, c2, c3]… etc…
merging should happen on the basis of indices only. [(merge a1 b1 c1) (merge a2 b2 c2)….]
If the N vectors were all of the same length, or you were willing to stop with the shortest one, then (apply map merge list-of-vectors)
would do it.
because (map merge list1 list2 list3)
does what you want for 3 lists/vectors/sequences of maps, and (map merge list1 list2 list3 list4)
does what you want for 4 sequences of maps, etc. apply
will handle any number of such lists in the list-of-vectors
argument.
but if you want the result to have maps for the longest of the lists, and they can be of different length, then that does not quite do what you want.
thanks a lot @U0CMVHBL2 this advice really helps.. Will implement the solution and update you.
Thanks andy with your help I was able to solve the problem I was having with following code:
(defn merge-styles
[& args]
(let [max-count (apply max (map #(count %1) args))
items (map #(take max-count (concat %1 (repeat nil))) args)]
(apply map merge items)))
Thanks again for your advice.Any pattern on processing a large map within a data processing pipeline, with each step in the pipeline add additional scoped key/value pair into the map? I found it hard to trace the logic, as each pipeline transformation functions must be declared before the main processing pipeline function, it’ll be confusing quickly if the map entries is large and over 3/4 transforming steps… 😅
im getting really stressed with this HTML escaping stuff 😞 I have a markdown file that is creating HTML (and right now I'm trying markdown->hiccup code), but I want to ensure that any HTML the user writes is NOT executed, but stuff created by markdown is. It's pretty frustrating because:
- If I attempt to sanitise it before processing, code
blocks in MD show the escape html and it looks ugly
- If I sanitise it after, it sanitises the HTML produced by my markdown translator
- If I use https://github.com/mpcarolin/markdown-to-hiccup, the compiler actually translates HTML written by the user into hiccup for them. I imagine this is because it goes markdown string
-> html string
-> hiccup data
.
I really don't know how to do this, but its such a common pattern. I can write <button> button </button>
here and it looks just fine, no escaping, and yet writing <button> button </button> here doesn't get rendered. What's the solution?
I even followed the example on the readme, but the result is the OPPOSITE of what I wanted.
(-> (:post-summary p)
(md/md->hiccup {:encode? true})
(md/component))
Pros: It doesn't escape HTML produced by markdown and so hiccup works like normal
Cons: For some reason, it appears to escape HTML AFTER converting to hiccup, meaning that the badbutton code is no longer HTML anymore.I actually did get it working using markdown-clj
, my error previously was that I didn't know state
was a map, so I got it. However, my single-line code blocks aren't quite working. Let me show some code
[:div
{:dangerouslySetInnerHTML
{:__html (md/md->html
(:post-summary p)
:replacement-transformers
(cons escape-html mdt/transformer-vector))}}]
(defn- escape-html
"Change special characters into HTML character entities."
[text state]
(let [sanitized-text
(clojure.string/escape text
{\& "&"
\< "<"
\> ">"
\" """
\' "'"})]
[(if (not (or (:code state) (:codeblock state)))
sanitized-text text) state]))
It looks okay apart from the inline code.
I'm not also trying to get highlight.js
to work, but that doesn't seem to do anything going off of their usage page
Hi y'all I'm having hard time figuring out if what i'm reading is current or not, what would be the recommended source for documentation??
specially for clojurescript
@gonzalo.romano I've used this in the past https://cljs.github.io/api/ you can change the version to make sure you stay up to date with what you're working with You may also be interested in https://clojurescript.org/reference/documentation
(set! (.-style.background-color e) "transparent")
Is this how I'd go about changing something's colour to transparent using clojurescript interop?Ah I got it actually!
(aset e "style" "background-color" "transparent")
I didn't know that doing .-style
returned another object that you had to get properties of
I thought style.background-color
was the property
that was quick 🙂
I am doing this exercise: https://www.reddit.com/r/dailyprogrammer/comments/ab9mn7/20181231_challenge_371_easy_n_queens_validator/ The loops seem to be ending early. In diagonal-collision? I want to go through each queen in an "outer" recursion, checking that queen with each other queen in the "inner" recursion. But the entire thing stops after a few iterations.
there's no implicit looping, so there's likely a case where you should recur but don't, or you recur in a way that skips cases -- I don't quite understand the code well enough to tell you precisely where it goes wrong
it would help to make things simpler, for example (first (drop 1 x))
is idiomatically (second x)
or (nth x 1)
also the code might be more straightforward with a hash-map from number to number, instead of a vector which requires finding an index via scan
though I guess this is a two way mapping, so a vector might still be simpler
also the pattern used comparison likely has a better higher order equivalent, eg. (for [q1 queens q2 queens :when (not= q1 q2)] ...)
(for is a comprehension and not a looping construct, it generates a lazy-seq)
this gets the x/y for each item, and gets all possible pairs as a lazy-seq
user=> (let [queens (map list (range) [5 8 2 3 7 1 3 6])] (for [q1 queens q2 queens :when (not= q1 q2)] [:comparing q1 q2]))
([:comparing (0 5) (1 8)] [:comparing (0 5) (2 2)] [:comparing (0 5) (3 3)] [:comparing (0 5) (4 7)] [:comparing (0 5) (5 1)] [:comparing (0 5) (6 3)] [:comparing (0 5) (7 6)] [:comparing (1 8) (0 5)] [:comparing (1 8) (2 2)] [:comparing (1 8) (3 3)] [:comparing (1 8) (4 7)] [:comparing (1 8) (5 1)] [:comparing (1 8) (6 3)] [:comparing (1 8) (7 6)] [:comparing (2 2) (0 5)] [:comparing (2 2) (1 8)] [:comparing (2 2) (3 3)] [:comparing (2 2) (4 7)] [:comparing (2 2) (5 1)] [:comparing (2 2) (6 3)] [:comparing (2 2) (7 6)] [:comparing (3 3) (0 5)] [:comparing (3 3) (1 8)] [:comparing (3 3) (2 2)] [:comparing (3 3) (4 7)] [:comparing (3 3) (5 1)] [:comparing (3 3) (6 3)] [:comparing (3 3) (7 6)] [:comparing (4 7) (0 5)] [:comparing (4 7) (1 8)] [:comparing (4 7) (2 2)] [:comparing (4 7) (3 3)] [:comparing (4 7) (5 1)] [:comparing (4 7) (6 3)] [:comparing (4 7) (7 6)] [:comparing (5 1) (0 5)] [:comparing (5 1) (1 8)] [:comparing (5 1) (2 2)] [:comparing (5 1) (3 3)] [:comparing (5 1) (4 7)] [:comparing (5 1) (6 3)] [:comparing (5 1) (7 6)] [:comparing (6 3) (0 5)] [:comparing (6 3) (1 8)] [:comparing (6 3) (2 2)] [:comparing (6 3) (3 3)] [:comparing (6 3) (4 7)] [:comparing (6 3) (5 1)] [:comparing (6 3) (7 6)] [:comparing (7 6) (0 5)] [:comparing (7 6) (1 8)] [:comparing (7 6) (2 2)] [:comparing (7 6) (3 3)] [:comparing (7 6) (4 7)] [:comparing (7 6) (5 1)] [:comparing (7 6) (6 3)])
the (map list (range) [...])
construct pairs up an index with a value at that index
this still returns each pair twice in flipped order though
Ah, a list comprehension should be much better. I didn't really like my function that went through everything, but I also didn't want to rethink it before I got it working, since I have no idea why it doesn't work.
This is what I ended up with, thank you! Only thing I'm confused about is (map list (range) qs)). How does it work?
map takes a function plus any number of collections
it calls the function on the first element of each coll, then the next item on each, etc. until one of them ends
user=> (map list [:a :b :c] '[dog cat cow elephant])
((:a dog) (:b cat) (:c cow))
range returns numbers from 0 on - without any args it returns an indefinite series of numbers
don't use def inside defn - unlike in scheme, def always creates a global
use let instead
also, instead of the low level .contains
method, the usual approach would be to use (some true? collisions)
- that returns true for the first collision it finds (and stops realizing the lazy seq at that point, no need to calculate more results)
I have an async channel adapted from a node event emitter. I have a function which pushes events from the emitter to a channel - but there is also a method cancel
to stop the event emitter. The event emitter basically subscribed to ongoing changes and when one wants to stop listening one has to cancel
the subscription.
Now, my question is how I would best design the function to be able to get a channel but still be able to cancel the subscription.
Should I return an array as [cancel-fn channel]
or is there a way to only return the channel and make the (close! channel)
also cancel the subscription?
the publisher gets a result, true or false when writing to the channel, false means the channel is closed
I might want to instead use two channels to get full duplex communication between things, because closing a channel isn't something you can wait for
the problem with relying on closing the channel is the sender won't find out the channel is closed until the sender tries to send something, which not always acceptable
>I might want to instead use two channels to get full duplex communication between things Can you maybe elaborate on this? What would the second channel be for? I currently fail to see the use 😞
instead of having a single channel that events flow from producer to consumer through, you have two channels, one that events flow from producer to consumer through and one that the consumer can use to signal that it is done consuming to the producer