Fork me on GitHub
#beginners
<
2021-05-23
>
practicalli_john09:05:44

I think I need some clojure regex help. I'd like to remove a pattern of characters toward the end of a string. For example "persons name ABC12345" would return "persons name". If there is a space after the in the string the pattern would not be removed. I've been experimenting with re-seq, replace and re-pattern but havent found the right regex. Also, any good articles on using boundaries in regex would be useful, as I suspect defining boundaries might help

indy10:05:08

(defn something [s] 
   (if-let [match (re-matches #"^(persons name) *\S+" s)]
     (second match)
     s))

indy10:05:53

(something "persons name *ABC12345") => "persons name"
(something "persons name * ABC12345") => "persons name * ABC12345"

indy10:05:02

Pretty sure it can be done more succinctly using a better capturing group and re-find

noisesmith16:05:45

a note: there's no such thing as a "clojure regex" - on the jvm clojure uses java regex, in cljs clojure uses javascript regex - this is the best cross platform regex guide I've found and I return to it often: http://www.regular-expressions.info/ - it has great comparison of the featureset / syntax of various regex systems (from grep, ed, sed, java, perl, c ...)

noisesmith16:05:36

bad site design / UI, but top quality info that's well organized once you figure out how it's meant to be navigated

Michaël Salihi09:05:34

Hi! If I want to concat 3 items: 1. A simple hash map {:url url :label "Previous"} 2. A vector of hash maps [{:url (str url item) :label (str item)}{:url (str url item) :label (str item)}...] return by a for loop 3. A simple hash map {:url url :label "Previous"} Is there a better way - more idiomatic - to do this than to surround simple maps with a vector like I do now?

(let [previous-link {:url url :label "Previous"}
      links (for [item (range 1 (inc page-number))]
              {:url (str url item) :label (str item)})
      next-link {:url url :label "Next"}]
  (concat [previous-link] links [next-link]))

indy10:05:51

Not really better or more idiomatic than what you have here,

(flatten [previous-link links next-link])

indy10:05:59

What would've been idiomatic is to have something like

(->> some-list
     (cons el2)
     (push el3))
But push doesn't exist for lists since it's O(n).

Michaël Salihi13:05:51

Perfect @UMPJRJU9E, thanks. I prefer your flatten solution that mine. 👍

Azzurite13:05:00

how do I do get the same result as (rest (rest something)) without looking so stupid? 😄

dharrigan13:05:21

(nthrest something 2)

dharrigan13:05:15

user=> (def something [1 2 3 4 5 6 7 8])
#'user/something
user=> (rest (rest something))
(3 4 5 6 7 8)
user=> (nthrest something 2)
(3 4 5 6 7 8)

dharrigan13:05:02

This talks about it more detail, in particular the difference between nthrest and drop, with drop being lazy.

Azzurite13:05:49

and another thing I've been trying to solve for a while but can't do it, is there a way to get rid of the duplication in this macro code:

(if docstring
  `(rum/defc
     ~sym
     ~docstring
     ~'< reactive
     [email protected]
  `(rum/defc
     ~sym
     ~'< reactive
     [email protected]))
I can't do the if inside because then the if gets added to the output...

Azzurite14:05:01

well after spending another 30 min on this I feel stupid...

(let [definition `(rum/defc
                    ~sym
                    ~'< reactive
                    [email protected])]
  (if docstring
    (concat 
      (take 2 definition)
      [docstring]
      (drop 2 definition))
    definition))

kennytilton11:05:46

That looks brittle. How about using [email protected] splicing with the value (when docstring [docstring])? [email protected] on nil will not inject a nil or anything else. I think. :)

Dieter18:05:58

Hi, can someone help to transform a async/await js example into cljs? I use shadow-cljs, installed an npm package and required it in a namespace (package beckhoff-js https://www.npmjs.com/package/beckhoff-js ). The example is:

const AdsClient = require('beckhoff-js');

const options = {
  target: {
    host: "172.16.21.6",
    netID: "5.9.36.191.1.1",
    amsPort: 801
  }
};

const client = new AdsClient.default(options);
client
  .connect()
  .then(async () => {
    // Read a tag
    const bTest = await client.readTag(".bTest");
    console.log('bTest value is', bTest);
  });
The cljs version so far:
(ns app
  (:require [reagent.core :as r]
            [reagent.dom :as rdom]
            ["beckhoff-js" :as adsclient]))

(comment

  (def client (adsclient/default. #js{:target #js{:host "127.0.0.1" :netID "172.26.0.1.1.1" :amsPort 851}}))

  (.connect client)) 
Creating the client instance works fine. The .connect returns #object[Promise [object Promise]], but the browser console returns an error: Uncaught (in promise) TypeError: net_1.Socket is not a constructor... I had a look at cljs js promise interop and tried some things with .then, but no success