Rashi Bhalla
Rashi Bhalla

Reputation: 25

Changing nested element of an atom

I am trying to change value of an atom:

#atom[{{:other-site-conf 2499/2500, :own-unconf|other-conf [[30.752499999999998 1.0126843266559153 12] "Humidity"], :other-site-unconf 1/2500, :both-unconf [[27.563987107797804 4.984857204039122 7511] "Humidity"], :site-id 1, :other-site-quant 0.86235090749618} {:other-site-conf 2497/2500, :own-unconf|other-conf [[22.976875 0.09445843442135488 4] "Temperature"], :other-site-unconf 3/2500, :both-unconf [[20.920551354838697 1.0618445458730512 7511] "Temperature"], :site-id 0, :other-site-quant 0.7673990631272951}} 0x5bf8ef86]

In this I want to change map values inside :both-unconf of second map that is of :site-id 0

I have tried using:

(swap! prob-cond update-in [1 1 :both-unconf 1 1 0] 22)

but not working.

Upvotes: 0

Views: 114

Answers (4)

Rashi Bhalla
Rashi Bhalla

Reputation: 25

I have obtained the required output by: (reset! prob-cond (first @prob-cond)) (swap! prob-cond #(update-in % [1 :both-unconf 0 0] (constantly 22)))

Upvotes: 0

rmcv
rmcv

Reputation: 1976

This is because your top level data structure is a map. So when you do assoc-in (or update-in) with [1 ...] it will create/update the map entry with key=1.

| | ks=> [1]
| (assoc-in {:a :b} ks 42)=> {:a :b, 1 42}
| | ks=> [1 :both-unconf]
| (assoc-in {:a :b} ks 42)=> {:a :b, 1 {:both-unconf 42}}
| | ks=> [1 :both-unconf 0]
| (assoc-in {:a :b} ks 42)=> {:a :b, 1 {:both-unconf {0 42}}}
| | ks=> [1 :both-unconf 0 0]
| (assoc-in {:a :b} ks 42)=> {:a :b, 1 {:both-unconf {0 {0 42}}}}

Now change your top level structure into a vector, with the second element as a map:

[:a {:both-unconf [[41 43]]}]
| | ks=> [1]
| (assoc-in [:a #] ks 42)=> [:a 42]
| | ks=> [1 :both-unconf]
| (assoc-in [:a #] ks 42)=> [:a {:both-unconf 42}]
| | ks=> [1 :both-unconf 0]
| (assoc-in [:a #] ks 42)=> [:a {:both-unconf [42]}]
| | ks=> [1 :both-unconf 0 0]
| (assoc-in [:a #] ks 42)=> [:a {:both-unconf [[42 43]]}]

Upvotes: 0

Alan Thompson
Alan Thompson

Reputation: 29958

You have made a mistake with your data, I believe:

(def data
  {{:other-site-conf       2499/2500,
    :own-unconf|other-conf [[30.752499999999998 1.0126843266559153 12] "Humidity"],
    :other-site-unconf     1/2500,
    :both-unconf           [[27.563987107797804 4.984857204039122 7511] "Humidity"],
    :site-id               1,
    :other-site-quant      0.86235090749618}
   {:other-site-conf       2497/2500,
    :own-unconf|other-conf [[22.976875 0.09445843442135488 4] "Temperature"],
    :other-site-unconf     3/2500,
    :both-unconf           [[20.920551354838697 1.0618445458730512 7511] "Temperature"],
    :site-id               0,
    :other-site-quant      0.7673990631272951}}
  )

Here data is a map with a single MapEntry. Both the key and value of this MapEntry are, in turn maps. This is almost certainly not what you wanted.

I am assuming you wanted to have a vector containing 2 maps, like so:

(def data
  [{:other-site-conf       2499/2500,
    :own-unconf|other-conf [[30.752499999999998 1.0126843266559153 12] "Humidity"],
    :other-site-unconf     1/2500,
    :both-unconf           [[27.563987107797804 4.984857204039122 7511] "Humidity"],
    :site-id               1,
    :other-site-quant      0.86235090749618}
   {:other-site-conf       2497/2500,
    :own-unconf|other-conf [[22.976875 0.09445843442135488 4] "Temperature"],
    :other-site-unconf     3/2500,
    :both-unconf           [[20.920551354838697 1.0618445458730512 7511] "Temperature"],
    :site-id               0,
    :other-site-quant      0.7673990631272951}
   ])

You can change the value like so:

  (let [state (atom data)
        result (swap! state #(assoc-in % [1 :both-unconf 0 0] 42)) ]

with result:

[{:other-site-conf 2499/2500,
  :own-unconf|other-conf
  [[30.752499999999998 1.0126843266559153 12] "Humidity"],
  :other-site-unconf 1/2500,
  :both-unconf
  [[27.563987107797804 4.984857204039122 7511] "Humidity"],
  :site-id 1,
  :other-site-quant 0.86235090749618}
 {:other-site-conf 2497/2500,
  :own-unconf|other-conf
  [[22.976875 0.09445843442135488 4] "Temperature"],
  :other-site-unconf 3/2500,
  :both-unconf [[42 1.0618445458730512 7511] "Temperature"],
  :site-id 0,
  :other-site-quant 0.7673990631272951}]

Upvotes: 0

Dan Markhasin
Dan Markhasin

Reputation: 792

You need to pass swap! a function.
(swap! prob-cond #(update-in % [1 1 :both-unconf 1 1 0] (constantly 22))

Upvotes: 1

Related Questions