This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-05
Channels
- # announcements (1)
- # asami (25)
- # babashka (78)
- # beginners (24)
- # clojure (15)
- # clojure-europe (21)
- # clojure-losangeles (4)
- # clojure-nl (1)
- # clojure-norway (13)
- # clojure-uk (11)
- # cursive (17)
- # datomic (29)
- # events (1)
- # fulcro (4)
- # hyperfiddle (6)
- # jobs (1)
- # lsp (20)
- # malli (9)
- # off-topic (7)
- # pedestal (1)
- # polylith (2)
- # practicalli (1)
- # rdf (7)
- # reitit (1)
- # remote-jobs (1)
- # spacemacs (17)
- # specter (24)
- # vim (1)
Hello 👋 I'd like to transform and maybe filter in one go, some thing like this:
(sp/transform [sp/INDEXED-VALS]
(fn [[i x]] (let [v (some-fn x)]
(if (some-pred v) [i v] sp/NONE)))
[1 2 3 4])
is this possible in specter?In what? I return i
and v
What do you mean? it changes the data. I want it in the overall data for later computations
I want to know the original position of each transformed value in case it passes the pred
(sp/transform [sp/INDEXED-VALS] (fn [[i x]] [i x]) [1 2 3 4])
=> [1 2 3 4], not [[0 1], [1 2] ...]
Currently I can't test that but i think it did return the values with the indices but when I introduced the NONE in order to omit values it throws (something about keyword I'm guessing it tries to do something to NONE)
My code is performance critical so I'm trying to do the transformation and the filtering in one go. My current implementation is with reduce-kv so if I'm not surpassing that it won't do. If I compare only the transformation without the filtering, specter wins (probably because of transient). Then I tried to add the filtering using NONE and failed
no can't find it, once you use INDEXED-VALS, when you "leave" you're returning the whole vector. And using view + map-indexed would defeat the purpose
I cooked this abomination:
(sp/multi-transform [(sp/view #(map-indexed vector %)) sp/ALL (sp/view (fn [[i x]] [i (some-fn x)])) (sp/if-path (fn [[i x]] (some-pred x)) (sp/terminal identity) (sp/terminal-val sp/NONE))] [1 2 3 4])
thank you @U02F0C62TC1 I did some benchmarking on a couple of options and this is what cameout:
(timeit
10000
(sp/select [sp/INDEXED-VALS
(sp/view (fn [[i x]] (let [v (inc x)]
(if (even? v) none [i v]))))
(sp/pred #(-> % none? not))]
(vec (range 100)))) := 1150
(timeit
10000
(sp/multi-transform [(sp/view #(map-indexed vector %))
sp/ALL
(sp/view (fn [[i x]] (let [v (inc x)]
(if (even? v) none [i v]))))
(sp/if-path (fn [[i x]] (-> x none? not))
(sp/terminal identity)
(sp/terminal-val sp/NONE))]
(vec (range 100)))) := 1725
(timeit
10000
(reduce-kv
(fn [acc i o]
(let [v (inc o)]
(if (even? v)
acc
(conj acc [i v]))))
[]
(vec (range 100)))) := 445
if you're going to use clojure why not use transducers ?
(into [] (comp (map inc) (filter even?)) ...)
Might also be perfomant