Fork me on GitHub
#beginners
<
2018-06-24
>
sova-soars-the-sora00:06:25

I'm storing maps in an atom and I want to find a map with a given :k-v ... like :post_id 10018 and i'd like to return the whole associated map.

seancorfield00:06:13

@sova So your atom is a sequence of maps?

seancorfield00:06:03

(filter (fn [{:keys [post_id]}] (= 10018 post_id)) @my-atom) -- something like that ? (which would return all matching maps)

sova-soars-the-sora00:06:28

yo! that's wonderful

sova-soars-the-sora00:06:37

that's exactly right, the atom is a sequence of maps.

stardiviner02:06:11

How to guess a encoded string's encoding method? like base64, etc?

sova-soars-the-sora03:06:17

How can i update a map that matches on a particular :k-v, that lives in a sequence of maps?

sova-soars-the-sora04:06:43

I'm trying something like (swap! page-threads update-in [:pagename boardname] assoc :thread-id thread-id) but it's not right

sova-soars-the-sora04:06:40

(def threads (atom [{:thread_id "10029"
                     :posts [17778 17780]}
                    {:thread_id 10031
                     :posts [17779]}
                    {:thread_id 10033
                     :posts [18881 18882 18883]}]))

mg04:06:59

@sova two thoughts: given these access patterns, maybe a map of maps would be more appropriate than a sequence of maps. Otherwise, use a vector of maps. Find the index in the vector of the maps you're interested in, then you can update them positionally

sova-soars-the-sora04:06:19

(def page-threads (atom [{:pagename "hax"
                          :threads [10029]}
                         {:pagename "top"
                          :threads [10031 10033]}]))

sova-soars-the-sora04:06:04

@michael.gaare that makes sense. so find out which index :pagename matches on boardname and then update via index...

sova-soars-the-sora04:06:53

these are both vectors of maps, right?

mg04:06:55

Although they make me kind of nervous. Are you using several atoms to get multiple views of the same data

mg04:06:16

That's an anti-pattern for atoms - the whole idea is that they provide atomic updates, a guarantee which is lost if you have to coordinate updates across more than one

sova-soars-the-sora04:06:03

well it might make sense to have everything live in one atom, but i am using 3 that are each one level deep, instead of one that is 3 levels deep

sova-soars-the-sora04:06:03

i would much rather find-and-replace by matching on :keys instead of looking up indices since there is no guarantee the index will not have changed...

sova-soars-the-sora04:06:39

but i'm not really sure how to use swap! to "seek and update" a particular {:mappity map}

sova-soars-the-sora04:06:15

of course, i'm open to any suggestions, including overall approach 😃

mg04:06:58

Well take the atom out of the picture for a second. How would you write a function to do this if it was just the map

sova-soars-the-sora04:06:43

assoc seems to be the way to go if the map already exists in the vector, otherwise, conj methinks

mg04:06:09

more broadly, you have to two do things in this function - find the thing(s) to update (since you're searching across the vals of a collection of maps), and then do the updates

sova-soars-the-sora04:06:40

yes. find index, use index to update?

mg04:06:11

so if you can write that, there's your swap function, and you don't have to worry about the index or something else changing underneath you since it will happen in an atomic swap operation

sova-soars-the-sora04:06:38

I don't know how to get the index for a matching map.

sova-soars-the-sora04:06:22

i naively tried (.indexOf v {:matching map}) but that does not seem to work.

sova-soars-the-sora04:06:39

since it only needs to be a partial match

mg04:06:46

perhaps something like:

(reduce-kv (fn [_ idx m]
             (if (= desired-value (:desired-key m))
               (reduced idx)))
           nil
           vector-of-maps)

mg04:06:55

that will return the index of the first match only

mg04:06:16

this one is probably a little nicer. Returns a collection of all matching indexes:

(keep-indexed (fn [idx m]
                (when (= desired-value (:desired-key m))
                  idx))
              vector-of-maps)

sova-soars-the-sora04:06:52

how does this even math

sova-soars-the-sora04:06:19

(reduce-kv) and (reduced idx) are magical

mg04:06:49

reduced is a way to short-circuit a reduce

sova-soars-the-sora05:06:19

well, now i have the index, so far so good

dpsutton05:06:02

do you understand why a vector and the index lead to an easy update-in statement?

dpsutton05:06:13

it was surprising (but understandable) the first time i heard it

dpsutton05:06:24

(update-in [{:a 0} {:a 0}] [1 :a] inc) => [{:a 0} {:a 1}]. vectors are associative just like maps. so the "key" for each entry is its index

sova-soars-the-sora05:06:47

that is very nice, i'm wrapping my mind around it gradually.

sova-soars-the-sora05:06:21

so now that I have a result that I want to store back in at atom, is it advisable to do an atomic replace on the whole atom? what if i have many many entries in my atom?

seancorfield06:06:45

You should replace your whole atom with a new value (atomically).

sova-soars-the-sora07:06:09

using something like reset! ?

curlyfry08:06:22

@sova Yes, or for example swap!

sova-soars-the-sora11:06:20

What if I want to have a sequence that is precisely count 100, and after reaching 100, the oldest entry gets kicked out once a new entry is added ? Can I achieve this behavior with a queue or is there something more native to clojure?

mfikes12:06:16

@sova Often, I will employ take as in

(as-> '(4 3 2 1) x (conj x 5) (take 4 x))

mfikes12:06:13

Perhaps queues are more efficient; I haven't used them frequently

(as-> #queue [1 2 3 4] x (conj x 5) (pop x))
^ this uses the ClojureScript queue literal syntax

sova-soars-the-sora12:06:36

Thanks @mfikes take is just what i was looking for. (take 100 (distinct ...)) works very nicely

ranmacar17:06:46

Hi! Anyone here tried replumb recently?

ranmacar17:06:51

I am getting confused, requiring it in my core.cljs leads to an error (can't find cognitect/transit.cljs). Should it only be used in the .clj?

Usman18:06:05

which is best language for embedded development node or python? Someone explain briefly ?

Radek21:06:53

Not sure how this is related to #beginners in this Slack group, but I would say neither of the two. Embedded systems are usually very simple computers running only your app (not even OS), so they’re usually written in C that operates very close to the actual hardware 🙂

Adam22:06:44

Hey, I'm trying to use a library yet not sure whats the correct ns for requiring it. the lib is clj-kafka-client and I tried:

(ns project.core
  (:require [clj_kafka_client]))
That didn't work. Any help would be much appreciated, thanks.

dpsutton22:06:53

it depends on if you want the consumer or producer. you want to require the specific namespace you need to use. most probably https://github.com/ylgrgyq/clj-kafka-client/blob/master/src/clj_kafka_client/consumer.clj#L1

dpsutton22:06:07

clj-kafka-client.consumer

dpsutton22:06:44

also, notice the hyphens - versus underscores _. Namespace names have hyphens, the associated files have underscores. I understand this is a jvm (java?) thing

dpsutton22:06:04

But the project.clj file will define the artifact name (here defproject clj-kafka-client "0.2.0-SNAPSHOT") and then your code just requires the namespace that you need.