specter

cjmurphy 2024-06-24T22:04:04.005739Z

I'm wanting to swap table-num s here, so that :id :a gets table-num 4 and :b gets 2:

(let [st {:tables [{:id :a, :table-num 2}
                   {:id :b, :table-num 4}]}
      swap-f (fn [st from to]
               (->> st
                 (s/setval [:tables s/ALL :table-num (partial = from)] to)
                 (s/setval [:tables s/ALL :table-num (partial = to)] from)))]
    ;; Unfortunately this is true:
    (= {:tables [{:id :a, :table-num 2} {:id :b, :table-num 2}]}
      (swap-f st 2 4)))
As you can see it doesn't work out, they both end up with table-num 2. How should I achieve this kind of swapping operation with Specter?

cjmurphy 2024-06-25T00:01:46.887849Z

Oh I see what I'm doing wrong! Kind of obvious now. If I do them separately then merge the two different st's I'll be fine.

nathanmarz 2024-06-25T00:38:06.805369Z

here's an easier way to do it: (transform (subselect :tables ALL :table-num) reverse data)

1
cjmurphy 2024-06-25T00:57:59.758619Z

In reality there's more than two, but just two to be swapped, so a slight variation did the trick:

(s/transform (s/subselect :tables s/ALL :table-num #{from to}) reverse st)