Skip to content
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

Add more examples with nested maps #127

Closed
vspinu opened this issue Jun 19, 2016 · 6 comments
Closed

Add more examples with nested maps #127

vspinu opened this issue Jun 19, 2016 · 6 comments

Comments

@vspinu
Copy link

vspinu commented Jun 19, 2016

The docs are almost exclusively concerned with vectors. I am having a real strugle with the nested maps at the moment.

First, the following works but I would like to keep only matched elements and all my attempts with filterer failed.

(sp/transform [ALL (fn [[k v]] (:id v))]
              (fn [[k v]] [k :new])
              {:a {:id 1} :b {:kk 2}})
;; {:a :new, :b {:kk 2}}

I would like to see {:a :new} as a result.

Second, I was expecting the shorter version to work as well

(sp/transform [ALL :id]
              (fn [[k v]] [k :new])
              {:a {:id 1} :b {:kk 2}})

but it gives Key must be integer error.

What am I missing here? Thanks.

@aengelberg
Copy link
Contributor

The key concept I think you're missing is that when doing a "transform", if items are not navigated to (because predicates fail), they are not removed from the result, but just untouched.

@aengelberg
Copy link
Contributor

Filterer won't help here either, because the values unmatched by the predicate will still appear, untouched, in the output structure.

When #117 is resolved there will be a more elegant way to omit values as a part of a transform.

@vspinu
Copy link
Author

vspinu commented Jun 20, 2016

So is there a way to omit untouched elements at all? Or we all have to wait till #117 is fixed?

@nathanmarz
Copy link
Collaborator

If all you want is the matched elements, then just use select:

(->> {:a {:id 1} :b {:kk 2}}
     (select [ALL (selected? LAST (must :id))])
     (into {})
     (setval MAP-VALS :new))

There's nothing to "fix" with #117, it would be a completely new feature. I'm not sure yet about whether adding the feature is the right thing to do.

@vspinu
Copy link
Author

vspinu commented Jun 22, 2016

then just use select:

I see. It's a bit on a verbose side and I have a feeling that such manual reconstruction won't play well with multi-level maps.

If "select -> manually re-constructing the map" is idiomatic specter then I have no complains. It's surprising though that specter does not provide "structure preserving" selects. IMHO it's a very useful feature and it would naturally complement existing functionality by doing transform and select in one blow.

@nathanmarz
Copy link
Collaborator

There's two ways to look at this. One is selecting what you need and then manipulating it as necessary, the other is to look at this as doing two separate transformations: first to replace map vals with :id keys with :new, and the second to remove map entries that don't have :id keys. With #117 the latter strategy would look like:

(transform MAP-VALS
  (fn [m] (if (contains? m :id) :new NONE))
  data)

It just happens to be in this case that both transformations could be specified concisely by a single transformation function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants