New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
No clean way to filter map keys or values? #277
Comments
You can just do:
|
Thank you for the quick response! I'm not sure how to use that approach in the context of the larger path I'm working with. Here's what I'm doing:
How could you write that such that Or is this too trivial and should I just be using the following instead, which does the same thing (and might be simpler?):
As I've been working with this, I found that the second (non-Specter) way is actually faster (~0.8 MS vs ~1.8 MS). So obviously I have a solution to my particular code problem, but your response will still be helpful for learning how to use Specter generally. |
This is all restructuring, so Specter's a little more verbose for this. Here's how you could do it in one path:
|
Thank you! I didn't know about The Clojure+encore implementation is still faster and more readable. Do you want Specter to be able to handle this type of restructuring more elegantly, or do you think it even should? If not, and the answer is just "different tools for different jobs," then we can close this issue. Thank you again for your help. |
Adding some kind of |
Specter is about targeting specific parts of a data structure and leaving the rest the same, so when you're doing a restructuring that's inherently outside the scope of the project. |
Understood! I've been using Specter to restructure complex, deeply nested |
For anyone interested, this type of transformation is better solved by meander: (require '[meander.epsilon :as me])
(def data
[{:id "ID 1" :a 1 :pick-me/b nil :pick-me/c 3}
{:id "ID 2" :a 5 :pick-me/b 6 :pick-me/c nil}])
(me/rewrite vd2
[{:id !id (me/keyword "pick-me" !k) (me/some !v)} ...]
{& ([!id {(me/keyword !k) !v}] ...)})
;; => {"ID 1" {:c 3}, "ID 2" {:b 6}}
For this case, imo the meander's version is much more readable than the specter version above provided by @nathanmarz . And I did some perf testing with the following data, which shows both solution have almost the same performance (def data
(into
[{:id "ID 1" :a 1 :pick-me/b nil :pick-me/c 3}
{:id "ID 2" :a 5 :pick-me/b 6 :pick-me/c nil}]
(repeat 10000 {:id "ID 2" :a 5 :pick-me/b 6 :pick-me/c nil})
)) Generally I find specter and meander are grealy complementary to each other.
Each of the two could do all these tasks (so does hand-crafted clojure code), but they have their own expertise where it could make a huge difference when used properly. |
I'm finding it kind of kludgy to try to filter out map keys or values, which is something I sometimes want to do inside of a large path without breaking out of my Specter mentality. For example, I would want something along these lines:
But the best I can come up with is:
or
So:
filterer
I need to useFIRST,
but that's not a very obvious hint when trying to grok it in the context of a big path. For values, I'd use LAST and that's also strange.Am I missing something here? Or am I misguided? There's plenty of other ways I could solve this problem but this seems like something Specter should be able to do cleanly...
The text was updated successfully, but these errors were encountered: