This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-08-01
Channels
- # aleph (3)
- # announcements (10)
- # babashka (6)
- # bangalore-clj (4)
- # beginners (91)
- # biff (7)
- # cider (25)
- # cljs-dev (1)
- # clojure (109)
- # clojure-europe (9)
- # clojure-norway (5)
- # clojure-uk (1)
- # clojurescript (22)
- # cursive (22)
- # data-science (1)
- # datalevin (5)
- # datomic (7)
- # emacs (7)
- # etaoin (1)
- # events (3)
- # graphql (12)
- # hyperfiddle (1)
- # inf-clojure (1)
- # lsp (69)
- # luminus (1)
- # meander (21)
- # nbb (4)
- # off-topic (27)
- # other-languages (12)
- # rdf (58)
- # releases (3)
- # remote-jobs (2)
- # rum (12)
- # shadow-cljs (4)
- # sql (3)
- # xtdb (1)
I am coming from the Javascript world. And what I am really struggling with is how I used string interpolation in Javascript.
In clojure, I want to map
over a list of domains to pass the domain into the query params.
I believe this is correct. But How do I do this with string interpolation? (note - domain-list is a global variable at the moment.)
(def domain-list (flatten (read-csv domain-file)))
(defn find-email []
(map (fn [domain-list]
(http/get "example/api/path"
{:as :json :query-params
{:api_key api
:domain domain-list
:limit 3}})) domain-list))
(http/get (apply str "example/api/path?api_key=" api "&domain=" domain))
do you mean something like that ?
mmmm let me test that. That might be it.
i'm not sure why you'd prefer this form, the version you posted is clearer, and should provide escaping
fair point
i guess i do not understand how domain-list is being looped through in my example
(for [domain domain-list] (http/get "..." {:query-params {:domain domain}}))
may be clearer ?
btw you should rename the argument: (map (fn [domain] (...)) domain-list)
That renaming clears up my confusion. the domain, in your example is like the argument passed to .map in JS?
well to be more precise, mapv
would be like array.map
, map
(and for
) returns a lazy seq so you may want to read about that
amazing, thanks @U02F0C62TC1
For something that looks slightly more like string interpolation you can also look at the format
-function
(map (fn [domain]
(format "" domain))
["a" "b" "c"])
=> ("<https://a/index.html>"
"<https://b/index.html>"
"<https://c/index.html>")
https://clojuredocs.org/clojure.core/formatright, my question is, how do I make it happen?
str can build strings, format is maybe what you would call string interpolation if you weren't used to being able to refer to variables inside strings
what would be the clojure way of doing this?
as in, dynamically creating url paths based on a list
People have written macros that do some kind of interpolation, but I haven't seen them mentioned in a few years, and I have never used them myself
I have, and they are actually pretty neat. I sometimes use clojure.core.strint
https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/strint.clj#L49-L76, and prefer it over format
in contexts like ClojureScript (where using goog.string.format
incurs a page size hit)
Given a folder with foo.clj
containing (ns foo) (defn -main [& args] (prn "Foo"))
and deps.edn
containing {:paths ["."]}
.
Running it shows a warning:
$ clj -m foo foo.clj
WARNING: Implicit use of clojure.main with options is deprecated, use -M
"Foo"
How to get rid of this warning?@eval2020 FYI you can remove the filename clj -M -m foo
What's the best way to relate values to data range ? eg
1 till 100 is category 1
101 till 120 is category 2
121 till 150 is category 3 .. etc
If the ranges are arbitrary and can't be computed then I think any ordered structure would do. A vector of maps like:
[{:cat 1 :start 1 :end 101} ...]
Or a https://clojuredocs.org/clojure.core/sorted-map might be what you're looking for.They are indeed arbitrary. Perhaps I rephrase the question: if I get a number 105, what's they easiest way to map it to category/number 2?
Maybe something like this:
(defn to-category [n]
(->> [1 101 121 151]
(take-while #(>= n %))
count))
Yeah, I was thinking cond
too and use keywords
(defn category [n]
(cond
(<= 1 n 100) :cat-1
(<= 101 n 120) :cat-2
(<= 121 n 150) :cat-3
:else :cat-4))
is there an elegant way, given a vector of potentially mixed types, to join consecutive strings while leaving other types as-is?
e.g. ["a" "b" "c" {:d :e}]
-> ["abc" {:d :e}]
I can do it with a somewhat verbose reduction but I'm wondering if there's an obvious solution I'm missing
did that help @U021MPXUQBF?
there are many ways to approach this, but I don't think you'll find any super elegant, bc operating on 'ragged' collections is often awkward
@U050ECB92 yeah, thanks, I forgot about that function here's my approach now. not sure if I can make it much better than this
(defn join-strings
[values]
(->> values
(partition-by (fn [x] (or (string? x) x)))
(map (fn [xs] (if (string? (first xs)) (str/join xs) (first xs))))))
I think something like this should work instead
(defn join-strings
[values]
(->> values
(partition-by string?)
(map (fn [xs] (if (string? (first xs)) (str/join xs) xs)))
flatten))
the issue is that partition-by
will partition by consecutive identical predicate values. so when I return the non-string values as-is, the identical ones are put in the same partition. but I ideally want all non-string values to have their own partitions
this is goofy but it technically works lol
(defn join-strings
[values]
(->> values
(partition-by (fn [x] (or (string? x) (rand))))
(map (fn [xs] (if (string? (first xs))
(str/join xs)
(first xs))))))
(defn join-strings
[values]
(->> values
(partition-by string?)
(mapcat (fn [xs] (if (string? (first xs)) [(str/join xs)] xs)))))
Is their a better way of doing this ?
(let [colors [["a" "foo"] ["b" "bar"] ["c" "quax"] ["d" "mouse"]]]
(clojure.walk/keywordize-keys (into {} colors)))
I'm thinking something like into
that I can pass a function to that tells it how to make the keys ?
My other thought was
(let [colors [["a" "foo"] ["b" "bar"] ["c" "quax"] ["d" "mouse"]]]
(into {} (for [[k v] colors]
{(keyword k) v})))
Or is this an OK way of doing that ?And with update-keys:
(let [colors [["a" "foo"] ["b" "bar"] ["c" "quax"] ["d" "mouse"]]]
(-> (into {} colors)
(update-keys keyword)))
@U013YN3T4DA, how did you get colors
as a vector of vectors? Maybe you can rewrite that function to produce a hash map directly and avoid that into {}
converting.this is my deps.edn:
{:paths ["src" "resources" "target/resources"]
:deps {org.clojure/data.json {:mvn/version "2.4.0"}
metasoarous/darkstar {:mvn/version "0.1.0"}
org.slf4j/slf4j-simple {:mvn/version "2.0.0-alpha5"}}}
and this is my require
(ns test.mysite.feat.home
(:require [clojure.data.json :as json]
[metasoarous.darkstar :as darkstar]))
and I am getting a ‘not on classpath error’ for darkstar… does anything look off in the above?Oh, copy paste error to here… that’s actually correct in the original… updating this version now to match what’s still throwing the error. Thanks for the catch!
There’s something off in the darkstar business.
wondering about my metasoarous.darkstar :as darkstar
getting this compilation error: failed: Extra input spec: :clojure.core.specs.alpha/ns-form
I had tried that repo (applied-science) as it hadn’t been pushed to clojars, which metasaurus later did and got a different error, but I’ll try again.
Gotcha… it’s because apparently it was originally fetched from github, but then later pushed to clojars… but appears in the link in metasaurus’s repo… confusing for someone like me, lol…
but I’ll try to use the
applied-science/darkstar {:git/url " "
:sha "541a3ff36065c59e92fe6aa61e41a4385ba6f893"}
in my deps.edn again, then I can require it as shown.here is the backstory…https://github.com/applied-science/darkstar/issues/3
whichever deps coordinate you use, that doesn't effect the names of the namespaces
ooooh… ok.
this I didn’t know.
stand by.
Well, how about them apples!! Thank you!! I had someone gotten into cribbing my requires off the dep in my deps.edn or equivalent.
is there an easy way to split a string around a somewhat complex regex (similar to clojure.string/split
) but keep the matches in the output sequence?
you mean like re-seq
You can match against a lookaround with clojure.string/split to keep the matches. It's mentioned in the first example on clojuredocs
Is there a way to do this without lookaround, particularly so that it works in ClojureScript as well? The JS lookaround syntax is the same but it's not supported by all browsers
If you can limit it to positive lookaheads, you should be fine afaik. If you really want to avoid them, I guess you could use clojure.string/replace beforehand to insert a character you know won't be in the original string, but it's a bit hacky:
(-> "camelCaseString"
(str/replace #"(\B[A-Z])" "¬$1")
(str/split #"¬"))
;; => ["camel" "Case" "String"]
Or you could roll your own fn:
(defn incl-split [string pattern]
(let [re (re-pattern (str "(.+?)(" pattern ".*)"))]
(loop [s string
res []]
(if-let [[_ match more] (re-matches re s)]
(recur more (conj res match))
(conj res s)))))
(incl-split "camelCaseString" #"\B[A-Z]")
;; => ["camel" "Case" "String"]
which you'd need to tailor to your needs. This, for example, wouldn't handle capture groups in the pattern.