Fork me on GitHub
#beginners
<
2023-01-30
>
M J12:01:14

I have a function that runs over the "first" of an array. If I change it to "second" it also works. However I want both, like I want to do this function on every item in the array, without repeatedly copying (first..., second..., and o on). Any ideas?

(reduce
                    (fn [result value]
                      ...)
                    []
                    (first (map as-hiccup (parse-fragment field))))

delaguardo13:01:33

if you already have a function that works for each elements from a collection then you can map over the collection using that same function: (map f collection) Looks like in your case f would be something like:

(fn [xs]
  (reduce
   (fn [result value]
     ...)
   []
   xs))
and collection is:
(map as-hiccup (parse-fragment field))

2
delaguardo13:01:46

https://www.braveclojure.com/core-functions-in-depth/ here you can find better explanation for core functions

pavlosmelissinos13:01:56

Sounds like you want to unnest the result of map. In that case what you're looking for is mapcat, not map.

M J13:01:21

Im fixing a bug in a code thats not mine,,, this is exactly what I have:

[(reduce
                    (fn [result value]
                      (if (some? (:data-marker (get value 1)))
                        (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                          (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                          (conj result ((keyword selected-language)
                                        (:field_name_html
                                         (first (filter (fn [x]
                                                          (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                              (:id x)))
                                                        display-fields))))))
                        (conj result value)))
                    []
                    (first (mapcat as-hiccup (parse-fragment field))))
                   
                   ]
I want to return everything not just the "first"

pithyless14:01:57

You have:

[(reduce (fn ..) (first (mapcat ...)))]
And you'd like:
(mapv (fn [hiccup] (reduce (fn ..))) (mapcat ...))
(if I understood correctly)

M J14:01:26

Yes. How exactly do I do it, Im trying but Im definitely missing something

pavlosmelissinos14:01:29

I don't understand what part of it doesn't work. What do you expect to get and what do you get instead? Can you describe the bug with a repro?

M J14:01:02

Im not successful in making the functin go over the whole list.

M J14:01:17

Okay I just want a function that just returns the items in (map as-hiccup (parse-fragment field))

pavlosmelissinos14:01:29

I don't get it. What do you mean "returns the items", isn't that what map does? Can you give an example?

pavlosmelissinos14:01:57

You want to run reduce on each of the items of (map as-hiccup (parse-fragment field)), right?

dgb2314:01:13

sometimes it's easier to write example data (which you can later use for a test). In a 'before' and 'after' fashion.

☝️ 2
pavlosmelissinos14:01:03

Exactly, that's what a repro is. Input data, expected output, actual output.

M J14:01:36

Okay, lets say I have this list ("1" "2" "3") and my function is applied only on the (first ("1" "2" "3") . I want it to loop over "1", "2", and "3"

pavlosmelissinos14:01:18

(map your-function your-list)

M J14:01:59

This is the input:

[(reduce
                    (fn [result value]
                      (if (some? (:data-marker (get value 1)))
                        (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                          (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                          (conj result ((keyword selected-language)
                                        (:field_name_html
                                         (first (filter (fn [x]
                                                          (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                              (:id x)))
                                                        display-fields))))))
                        (conj result value)))
                    []
                    (first (map as-hiccup (parse-fragment field))))]
(map as-hiccup (parse-fragment field)) contains this: ([:p {} Please insert your email address.] [:p {} 2nd line] [:p {} Please insert your email address.]) The first block of code returns this as a [:p]: Please insert your email address. I want it to return three divsof everything in the map....

dgb2314:01:37

ahh... your reducing function expects a single item. I think in order to make this work easily you could map over the whole thing instead. You move the mapcat outside the reduce and reference the item where you have your (first... expression. Does that make sense?

👍 2
dgb2314:01:24

It might look tlike this in the end I think?

(mapcat (fn [item]
          (reduce
           (fn [result value]
             (if (some? (:data-marker (get value 1)))
               (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                 (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                 (conj result ((keyword selected-language)
                               (:field_name_html
                                (first (filter (fn [x]
                                                 (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                     (:id x)))
                                               display-fields))))))
               (conj result value)))
           []
           (as-hiccup item))) (parse-fragment field))

👀 2
pavlosmelissinos14:01:33

I suppose you can't provide a short example of field @U03KB1C9N8M?

M J14:01:30

This is field: <p>Please insert your email address.</p><p>2nd line</p><p>Please insert your email address.</p> And this makes it into the map actually: (map as-hiccup (parse-fragment field)), which returns this: ([:p {} Please insert your email address.] [:p {} 2nd line] [:p {} Please insert your email address.]) So in the end we need to map over this (map as-hiccup (parse-fragment field))

pavlosmelissinos14:01:49

Ok good and what do you expect to get as the final result? You mentioned something about divs. Do you want to wrap each paragraph with a div, replace each :p with a :div or something else?

M J14:01:30

This list, exactly, I want to apply the function on it and not just the first item of this specific map. What it does is simply return this [:p], but the function adds more stuff to it before retuning the [:p]

M J14:01:19

LEts pretend fn doesnt exist, and I have this which returns [:p]: [(first (map as-hiccup (parse-fragment field)))] How do I map over the "map" and make it return all 3 [:p]'s....

dgb2314:01:49

you remove the call to first

☝️ 2
M J14:01:22

I want to loop over this (map as-hiccup (parse-fragment field))

dgb2314:01:23

and the vector literal

dgb2314:01:40

remove the square brackets and the frist

pavlosmelissinos14:01:07

This doesn't work? (map your-function (map as-hiccup (parse-fragment field)))

dgb2314:01:09

what you're doing is create a vector with a single item

M J14:01:57

For example, this

(println (map (fn [item]
                  item) (map as-hiccup (parse-fragment field))))
Still prints this: ([:p {} Please insert your email address.] [:p {} 2nd line] [:p {} Please insert your email address.]) It doesnt separate the map!! It just prints 3 times

pavlosmelissinos14:01:27

Please give an example of the output you expect

pavlosmelissinos14:01:00

I really don't understand what is wrong with that result

M J14:01:30

Instead of what it just printed, I want 3 separate prints: [:p {} Please insert your email address.] [:p {} 2nd line] [:p {} Please insert your email address.]

pavlosmelissinos14:01:28

Is this just for printing or do you want to pass this result to a different part of the code?

pavlosmelissinos15:01:52

If it's the former, replace map with run! and run println within each loop

pavlosmelissinos15:01:55

If it's the latter, you can't do it like this. map will give you a seq and the code that consumes it will have to map over each item again.

M J15:01:34

ITs not what I want guys. @U01EFUL1A8M got really close with the last big block of code here, but still didnt work

(mapcat (fn [item]
          (reduce
           (fn [result value]
             (if (some? (:data-marker (get value 1)))
               (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                 (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                 (conj result ((keyword selected-language)
                               (:field_name_html
                                (first (filter (fn [x]
                                                 (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                     (:id x)))
                                               display-fields))))))
               (conj result value)))
           []
           (as-hiccup item))) (parse-fragment field))

pavlosmelissinos15:01:04

What do you want?

M J15:01:44

Return the 3 [:p]'s in this map!: (map as-hiccup (parse-fragment field))

M J15:01:51

Not just the (first ...)

pavlosmelissinos15:01:45

> Not just the (first ...) @U01EFUL1A8M’s solution doesn't return just the first, so that's clearly not the problem

M J15:01:08

His solution doesn;t render

dgb2315:01:00

with "something like this" I implied "not tested" 😉

pavlosmelissinos15:01:17

You're obviously trying to do this inside a div in clojurescript, right?

pavlosmelissinos15:01:35

You might have to replace mapcat with map

M J15:01:55

For example I can do this and it works

[(reduce
                    (fn [result value]
                      (if (some? (:data-marker (get value 1)))
                        (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                          (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                          (conj result ((keyword selected-language)
                                        (:field_name_html
                                         (first (filter (fn [x]
                                                          (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                              (:id x)))
                                                        display-fields))))))
                        (conj result value)))
                    []
                    (first (map as-hiccup (parse-fragment field))))
                   (reduce
                    (fn [result value]
                      (if (some? (:data-marker (get value 1)))
                        (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                          (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                          (conj result ((keyword selected-language)
                                        (:field_name_html
                                         (first (filter (fn [x]
                                                          (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                              (:id x)))
                                                        display-fields))))))
                        (conj result value)))
                    []
                    (second (map as-hiccup (parse-fragment field))))
                   ]

M J15:01:32

But I dont wanna do that!

pavlosmelissinos15:01:20

(map
   (fn [fr]
     (reduce
      (fn [result value]
        (if (some? (:data-marker (get value 1)))
          (if (span-includes-hidden-filds? (:data-marker (get value 1)))
            (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
            (conj result ((keyword selected-language)
                          (:field_name_html
                           (first (filter (fn [x]
                                            (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                (:id x)))
                                          display-fields))))))
          (conj result value)))
      []
      fr)
     (map as-hiccup (parse-fragment field))))

pavlosmelissinos15:01:38

you might have to use mapv instead of map to force it to realize but this should work

M J15:01:48

Noe, I tried to print to see if this works:

(mapv
   (fn [fr]
     (println fr)
     ) (map as-hiccup (parse-fragment field)))
And it does, but this isnt working.......:
(mapv
                    (fn [fr]
                      (reduce
                       (fn [result value]
                         (if (some? (:data-marker (get value 1)))
                           (if (span-includes-hidden-filds? (:data-marker (get value 1)))
                             (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
                             (conj result ((keyword selected-language)
                                           (:field_name_html
                                            (first (filter (fn [x]
                                                             (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                                 (:id x)))
                                                           display-fields))))))
                           (conj result value)))
                       []
                       fr)) (map as-hiccup (parse-fragment field)))

pavlosmelissinos16:01:41

It's impossible to help you because "this isnt working" gives zero information about what the problem is, sorry.

Mark Wardle06:02:08

My advice is that it is better to stop talking about code and instead start talking about the data input and what you want as the result from that data input. Minimal examples of the data would be ideal - you could then use in testing this for example - and be much clearer for anyone to understand what you are trying to achieve.

4
M J18:02:51

You're right. I finally made it work, this was the solution:

(mapv
   (fn [fr]
     (hiccup-to-html (reduce
      (fn [result value]
        (if (some? (:data-marker (get value 1)))
          (if (span-includes-hidden-filds? (:data-marker (get value 1)))
            (conj result (get hidden-fields (keyword (get-id-value-from-string (:data-marker (get value 1))))))
            (conj result ((keyword selected-language)
                          (:field_name_html
                           (first (filter (fn [x]
                                            (=  (get-id-value-from-string (:data-marker (get value 1)))
                                                (:id x)))
                                          display-fields))))))
          (conj result value)))
      []
      [fr]))) (map as-hiccup (parse-fragment field)))
I had to do "hiccup-to-html" before reduce, and the fr element wrapped in [fr] like this

pithyless19:02:01

I tried to split apart your function into smaller steps. I'm not sure if I understood completely the intention of each of them, but perhaps this will be useful as a stepping stone:

(let [render-data-marker (fn [data-marker]
                          (let [id-data-marker (get-id-value-from-string data-marker)]
                            (if (span-includes-hidden-fields? data-marker)
                              [(get hidden-fields (keyword id-data-marker))]
                              (let [field-name (->> display-fields
                                                 (filter #(= id-data-marker (:id %)))
                                                 first)]
                                [(get-in field-name [:field_name_html (keyword selected-language)])])))) 
      render-hiccup (fn [value]
                       (if-some [data-marker (get-in value [1 :data-marker])]
                         (render-data-marker data-marker)
                         [value]))]
  (->> (parse-fragment field)
       (map as-hiccup)
       (map render-hiccup)
       (map hiccup-to-html)))

sheluchin17:01:08

How can I parse a date string like "Jan 30 2023" using java.time?

Martin Půda17:01:18

(LocalDate/parse "Jan 30 2023" (DateTimeFormatter/ofPattern "MMM dd yyyy"
                                                            Locale/UK))

sheluchin18:01:50

I was trying something like that but didn't use Locale/UK. I didn't think it was necessary.

Ben Lieberman18:01:27

I've never parsed a string in this particular format, but I don't think it is?

sheluchin18:01:43

Without it I get:

Text 'Sep 17 2017' could not be parsed at index 0

Martin Půda18:01:17

I think it isn't necessary- it depends on your default Locale- (Locale/getDefault). For "Jan", you need the correct Locale.

sheluchin18:01:58

Is there some effective way of learning java.time? I seem to fumble around with it every time I have to use it.

Ben Lieberman18:01:09

The only way I know of is to just use it consistently. I've used some wrappers and/or Clojure alternatives (like tick) but I'm pretty used to java.time now just by making it my go-to.

2
daveliepmann20:01:42

To add to Ben's point (which is the bulk of what worked for me), the java.time javadocs are some of the better ones. They reward a deep read. In particular, it really helped me to acknowledge and set aside my naive belief that its many classes, with such tiny pedantic distinctions, meant it's "one of those" Java packages – excessively OO and thus poorly designed. Those hair-splitting distinctions it makes between classes actually point to deep truths about the domain which were won only through decades of iterative implementation.

sheluchin20:01:54

Thanks for adding, @U05092LD5.

sheluchin00:02:08

How would I get DateTimeFormatter to work with an uppercase month like OCT?

sheluchin16:02:03

@U01RL1YV4P7 thanks. I looked at that last night too but couldn't get the incantation quite right. Here it is for posterity:

(defn str-to-date [date-str]
  (LocalDate/parse date-str
                   (.toFormatter
                    (doto (DateTimeFormatterBuilder.)
                      (.appendPattern "yyyy-")
                      (.parseCaseInsensitive)
                      (.parseLenient)
                      (.appendPattern "MMM-")
                      (.parseCaseInsensitive)
                      (.appendPattern "dd")
                      (.toFormatter Locale/US)))))

Ben Lieberman19:02:23

@UPWHQK562 you can use the .. macro here for the DateTimeFormatterBuilder, I think. Might help with some of the really deep chaining. (Then again I hate builder patterns, they drive me nuts.)

gratitude-thank-you 2
mister_m17:01:45

Is there a short hand in creating a map literal with a key that has the same name as the variable used to create the map? For example in JS if I have a variable x = 2 and say {x} this gives me a map with the form {x: 2}

Alex Miller (Clojure team)18:01:37

While I have written this same macro a couple times, I think I ultimately decided from a maintenance pov that it was better just to write it out (but you could have some code to generate the long form - macro for people!)

👍 2
cddr20:01:57

An e-mac[s]ro if you will

😃 2