Fork me on GitHub
#beginners
<
2023-07-18
>
Hendrik06:07:39

Is it possible to apply args to new constructor invocation? For example: (apply new myClass [1 2 3])

nikolavojicic07:07:13

Wrap it with anonymous function `(apply #(new myClass %&amp;) [1 2 3])` Wrong answer... try this instead: (new myClass (to-array [1 2 3]))

👍 6
💡 2
phill10:07:38

How is that? Isn't %& an array again? As described on this page: https://clojure.org/guides/learn/functions

👍 2
Hendrik11:07:25

I finally found this for java interop :

(clojure.lang.Reflector/invokeConstructor Klass (to-array [arg ...]))
https://stackoverflow.com/a/9084949/7483073

nikolavojicic16:07:00

Fixed my answer

joakimen15:07:18

How would you convert a vector to a map, while grouping values into a vector per key? My mind instantly went to SQL GROUP BY, so checked out https://clojuredocs.org/clojure.core/group-by, but couldn't think of a suitable f Example: ["a" 1, "b" 2, "a" 3] to {"a" [1 3], "b" [2]}

pppaul15:07:37

partition 2, then groupby first

joakimen15:07:18

It's close, but it puts the entire kv-pair as value

(->> ["a" 1, "b" 2, "a" 3]
     (partition 2)
     (group-by first))
;; => {"a" [("a" 1) ("a" 3)], "b" [("b" 2)]}

Caio Cascaes15:07:03

We can achieve with a bit of implementation, I'm not still aware by my mind if there is a ready function, but below we can achieve of what you need, although a bit ugly:

(->> ["a" 1, "b" 2, "a" 3]
        (partition 2)
        (group-by first)
        (map (fn [[k v]] {k (mapv (fn [[_ mv]] mv) v)}))
        (into {}))

nbardiuk16:07:34

I would use reduce probably

(->> ["a" 1 "b" 2 "a" 3]
     (partition 2)
     (reduce (fn [m [k v]]
               (update m k conj v))
             {}))

👍 6
Caio Cascaes16:07:23

The function above will return the value as list, not as vector, if it will be important for the purpose:

(->> ["a" 1 "b" 2 "a" 3]
     (partition 2)
     (reduce (fn [m [k v]]
               (update m k #(vec (conj % v))))
             {}))

👍 2
daveliepmann18:07:06

(reduce (fn [m [k v]]
          (update m k (fnil conj []) v))
        {}
        (partition 2 ["a" 1, "b" 2, "a" 3]))

👍 4
til 2
Bob B19:07:37

if it's the kind of thing that comes up a lot in a specific context, there are several libraries that include a 'group-by-reduce' or 'group-by-with-transform' function - ham-fisted and useful come to mind:

; example with org.flatland/useful
(require '[flatland.useful.seq :as s])
=> nil
(->> ['a 1 'b 2 'a 3]
     (partition 2)
     (s/groupings first second))
=> {a [1 3], b [2]}

👍 2
pithyless08:07:33

https://github.com/cgrand/xforms is probably overkill for this, but I like to think it gives you multiple hooks to transform/aggregate the data if you need to go deeper (which could become unwieldy if it was just reduce-within-reduce-within-reduce).

(require '[net.cgrand.xforms :as x])

(->> ["a" 1 "b" 2 "a" 3]
     (into {}
      (comp 
       (x/partition 2)
       (x/by-key first
        (comp 
         (map second)
         (x/into []))))))

tschady15:07:55

just for fun:

user=> (apply merge-with into (map (fn [[k v]] {k [v]}) (partition 2 ["a" 1, "b" 2, "a" 3])))
{"a" [1 3], "b" [2]}
in real life, I’d look for a way to build the desired collection right off the bat, instead of that initial vector.

👍 2
bschrag20:07:24

I've created my first substantial open-source project: https://github.com/bobschrag/clolog---full-featured logic programming (AKA "Prolog") embedded in/callable from and supporting calls to Clojure. Thanks to folks in this group for much gracious, generous help. Any advice about where/how to announce this?

👀 2
👏 2
Alex Miller (Clojure team)20:07:51

cool project! usually people announce libs here in #announcements (and minor updates in #releases)

👍 2
phill22:07:20

I didn't grasp what the (read-string (cl-format... was about, but aside from that, the project.clj states no dependencies and core.clj does not import any Java classes, so I was idly wondering whether if renamed to cljc everything would also work in ClojureScript and ClojureDart.

bschrag23:07:50

@U0HG4EHMH Yeah, I'm an old Common Lisper, so this was a shortcut at least until I learned more nuances of str, etc. Re CLJS (which I haven't picked up yet), there's a couple of calls to (Java's) .index-of and .contains that I suppose could be replaced (if, again, I hadn't taken shortcuts).

lambda-prompt 2
hifumi12310:07:01

I still use cl-format in various places because it sometimes produces cleaner code than using str Most obvious example for me would be something like

(cl-format nil "~:d thing~:p selected" n)
and it automagically produces the expected string for all n >= 0 , with commas and everything

👍 2