Hi all! Is it possible to get removed (via NONE
) element, for example:
(sr/setval [:elems
(sr/filterer (sr/must :id) (sr/pred= 1))
sr/FIRST] sr/NONE {:elems [{:id 1 :name "A"} {:id 2 :name "B"}]})
=> {:elems [{:id 2, :name "B"}]}
I want to get not only whole structure but also removed one: {:id 1 :name "A"}
.@nartamonov you can use transform instead, like this:
user=> (sr/transform
#_=> [:elems (sr/filterer (sr/must :id) (sr/pred= 1)) sr/FIRST]
#_=> (fn [x] (println x) sr/NONE)
#_=> {:elems [{:id 1 :name "A"} {:id 2 :name "B"}]})
{:id 1, :name A}
{:elems [{:id 2 :name "B"}]}
if you return NONE
from the transformation function it will remove the element just like setval
also, replace-in
might be of help: https://github.com/nathanmarz/specter/wiki/List-of-Macros#replace-in
actually, replace-in
is perfect:
user=> (sr/replace-in
#_=> [:elems (sr/filterer (sr/must :id) (sr/pred= 1)) sr/FIRST]
#_=> (fn [x] [sr/NONE x])
#_=> {:elems [{:id 1 :name "A"} {:id 2 :name "B"}]})
[{:elems [{:id 2 :name "B"}]} ([:id 1] [:name "A"])]
@nartamonov path
works equally in select
and setval
, so you can do something like it:
(let [data {:elems [{:id 1 :name "A"} {:id 2 :name "B"}]}
path [:elems ALL (if-path [:id #{1}] STAY)]]
{:data (setval path NONE data)
:removed (select path data)})
replace-in
is a option too@schmee Thanks, it works almost as I want. If instead x
we use [x]
then we'll get exactly the same structure (hashmap) that was removed:
(sr/replace-in
[:elems (sr/filterer (sr/must :id) (sr/pred= 1)) sr/FIRST]
(fn [x] [sr/NONE [x]])
{:elems [{:id 1 :name "A"} {:id 2 :name "B"}]})
=> [{:elems [{:id 2, :name "B"}]} ({:id 1, :name "A"})]
Though, don't understand why...ahh, sorry, I missed that the hash map changed into a seq, good that you found the solution
the reason is that the second element in the vector gets added to a sequence of return values, so if you have just a hash map it will be changed into a seq first, ie:
user=> (seq {:id 1, :name "A"})
([:id 1] [:name "A"])
vs
user=> (seq [{:id 1, :name "A"}])
({:id 1 :name "A"})
Now I see, thank you! 🙂
hi, is it possible to specter/transform
a k/v pair in a map to another map and then have that merged with the original siblings?
@johanatan you can use the submap
navigator for that
ah, ok. thx
was just reaching for clojure.walk
and learned recursive-path
and cond-path
instead — wasn’t disappointed =)