lib/attrsets: add mapAttrsToListRecursive(Cond) function#395160
lib/attrsets: add mapAttrsToListRecursive(Cond) function#395160wolfgangwalther merged 1 commit intoNixOS:masterfrom
Conversation
833a840 to
de8e584
Compare
There was a problem hiding this comment.
Nice work, code looks very lean.
I think your flatten approach might have a performance benefit vs a recursive fold as well.
This also related to #237776
Lgtm change overall. But needs testing and documentation.
I would give it a bit of time to let @roberth and @infinisil think about this as well.
de8e584 to
74980c6
Compare
74980c6 to
80156fd
Compare
8c1bf9f to
d552daa
Compare
fafb6cb to
8d1713b
Compare
1732abb to
5a9e090
Compare
|
I aligned the argument names in the code with those in the documentation and added assertions to make the functions more user‐friendly. |
If I understand correctly, one could implement the proposed collect' = pred: set: mapAttrsToListRecursiveCond (path: set: !(pred path set)) (path: value: { inherit path value; }) set;Using |
5a9e090 to
b169156
Compare
|
I re‐implemented the function using To avoid repeating |
|
Hello, I'm the author of #342330. I don't really mind which one we go with, but it feels a bit wasteful to reach for an noop function to use
Just in case you didn't know, you can verify this by configuring nix with envvars such as |
Agreed. I also expect an implementation of Perhaps we can just measure if an independent implementation of
Thank you. I didn’t know about the |
These were addressed.
b169156 to
e5ac84e
Compare
|
@hsjobeki sorry for the ping, do you think you could take another look at this at some point? |
|
We can always improve docs and tests later, so let's do it! |
|
While testing out the new function, trying to use it as I had imagined using Like, imagine you wanted to do the following: # input:
{
a.b.c.i-want-this-one = { x = 1; y = 2; };
x.y.z.i-want-this-one-too = { x = 1; y = 2; };
m.n.o.i-dont-want-this-one = { a = 3; b = 4; };
}
# output:
[
{ path = [ "a" "b" "c" "i-want-this-one" ]; value = { x = 1; y = 2; }; }
{ path = [ "x" "y" "z" "i-want-this-one-too" ]; value = { x = 1; y = 2; }; }
]You might try something like the following: lib.mapAttrsToListRecursiveCond
(path: _value: !(lib.elem (lib.last path) [ "i-want-this-one" "i-want-this-one-too" ]))
(path: value: { inherit path value; })
input
# output:
[
{ path = [ "a" "b" "c" "i-want-this-one" ]; value = { x = 1; y = 2; }; }
{ path = [ "x" "y" "z" "i-want-this-one-too" ]; value = { x = 1; y = 2; }; }
{ path = [ "m" "n" "o" "i-dont-want-this-one" "a" ]; value = 3; }
{ path = [ "m" "n" "o" "i-dont-want-this-one" "b" ]; value = 4; }
]It's not possible to rewrite the condition to exclude the extra leaf nodes, because the current implementation with unconditionally include everything that is not an attrset in the result. I'm wondering if it would be better to change |
I don't think we should change that, because this is how all the other |
Yes, that's why I'm wondering about renaming. I was under the impression that this PR would superseed #342330, but I'm not able to achieve what I'm trying to do with this implementation. Considering that making the change would still let you be able to achieve the normal map cond, I was hoping we could change it. Alternatively, implement |
|
I'd not change anything about this function, because it aligns with other functions that work the same way. If that means it does not replace #342330, then that PR should be continued.
This could be done later, if it turns out to be efficient enough, I'd say. |
You should be able to do: lib.mapAttrsToListRecursiveCond
(path: _value: !(lib.elem (lib.last path) [ "i-want-this-one" "i-want-this-one-too" "i-dont-want-this-one" ]))
(path: value: { inherit path value; })
inputThen do a second pass with This function seems to map any primitive leafs, independently of the
This shouldn't be possible currently right? Because While i think With the status quo, after @wolfgangwalther did the merge, i would try to use it as is. @h7x4 Could you probably try what is necessary to implement this in terms of collect' ? |
|
Going forward i would try to enhance #342330 and try to make it a superset of this function. I am not sure how both compare in performance (they need to be kind of comparable first) should we take a look at the stats and continue the discussion in the other PR? I would take an extra look at list allocations and then decide if its worth to unify one in the terms of another? |
|
De Morgan style: So we can spot that we always collect if the value is not an attribute set, independently from the predicate. we might accept this as consistent to According to the docs of (Sorry for splitting my thoughts, i hope you could follow :) ) |
I have been needing functionality to recursively transform an attribute set to a list quite often lately (for example in #391329), and I believe that having a generic implementation in
libmight be useful.Similar constructions are used in some of the generators in
lib.Things done
nix.conf? (See Nix manual)sandbox = relaxedsandbox = truenix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/)Add a 👍 reaction to pull requests you find important.