diff options
author | adisbladis <adisbladis@gmail.com> | 2023-11-27 01:42:32 +1300 |
---|---|---|
committer | adisbladis <adisbladis@gmail.com> | 2023-11-27 11:37:57 +1300 |
commit | 544a1d375b47de09d6610c2059588032a9d8c192 (patch) | |
tree | dd339d12766237fedc328042a0b8a4a2164d8841 /lib | |
parent | 7e07b3ecd55ac85675c26d9b09fab9996c410681 (diff) |
lib.attrsets.attrByPath: Don't allocate one extra list per lookup recursion
Using `tail` in a recursive loop like this needlessly allocates. This changes the loop to look up by list index instead.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/attrsets.nix | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/lib/attrsets.nix b/lib/attrsets.nix index 107570627c66a..52bc131ef40f2 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -34,12 +34,20 @@ rec { default: # The nested attribute set to select values from set: - let attr = head attrPath; + let + lenAttrPath = length attrPath; + attrByPath' = n: s: ( + if n == lenAttrPath then s + else ( + let + attr = elemAt attrPath n; + in + if s ? ${attr} then attrByPath' (n + 1) s.${attr} + else default + ) + ); in - if attrPath == [] then set - else if set ? ${attr} - then attrByPath (tail attrPath) default set.${attr} - else default; + attrByPath' 0 set; /* Return if an attribute from nested attribute set exists. @@ -60,12 +68,14 @@ rec { e: let lenAttrPath = length attrPath; - hasAttrByPath' = n: s: let - attr = elemAt attrPath n; - in ( - if n == lenAttrPath then true - else if s ? ${attr} then hasAttrByPath' (n + 1) s.${attr} - else false + hasAttrByPath' = n: s: ( + n == lenAttrPath || ( + let + attr = elemAt attrPath n; + in + if s ? ${attr} then hasAttrByPath' (n + 1) s.${attr} + else false + ) ); in hasAttrByPath' 0 e; |