From c7c30eb4520d2c087249bcf238f08cb8a752f8e9 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 30 Sep 2024 18:05:30 +0200 Subject: [PATCH 1/3] lib: improve `filterAttrs` Co-authored-by: Silvan Mosberger --- lib/attrsets.nix | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/attrsets.nix b/lib/attrsets.nix index 8bb4ef972fd8..2e8e9a05599a 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -644,8 +644,7 @@ rec { filterAttrs = pred: set: - listToAttrs (concatMap (name: let v = set.${name}; in if pred name v then [(nameValuePair name v)] else []) (attrNames set)); - + removeAttrs set (concatMap (name: if pred name set.${name} then [ ] else [ name ]) (attrNames set)); /** Filter an attribute set recursively by removing all attributes for From 83e1488c6d73683d8d4b52bed8563a12107b7d24 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 30 Sep 2024 18:05:50 +0200 Subject: [PATCH 2/3] lib/tests: test `filterAttrs` --- lib/tests/misc.nix | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/tests/misc.nix b/lib/tests/misc.nix index 116d86cdfb3f..72b3d630b8da 100644 --- a/lib/tests/misc.nix +++ b/lib/tests/misc.nix @@ -47,6 +47,7 @@ let evalModules extends filter + filterAttrs fix fold foldAttrs @@ -1102,6 +1103,25 @@ runTests { }; }; + testFilterAttrs = { + expr = filterAttrs (n: v: n != "a" && (v.hello or false) == true) { + a.hello = true; + b.hello = true; + c = { + hello = true; + world = false; + }; + d.hello = false; + }; + expected = { + b.hello = true; + c = { + hello = true; + world = false; + }; + }; + }; + # code from example testFoldlAttrs = { expr = { From 1de8e072168d6be15e722a7f745d25f247c3496a Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 31 Oct 2024 16:30:07 +0100 Subject: [PATCH 3/3] lib: refactor `filterAttrs` `filter` is a primop which is designed for this task, and it saves the allocation of some singleton lists here. --- lib/attrsets.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/attrsets.nix b/lib/attrsets.nix index 2e8e9a05599a..f4b03e5b53aa 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -7,7 +7,7 @@ let inherit (builtins) head length; inherit (lib.trivial) isInOldestRelease mergeAttrs warn warnIf; inherit (lib.strings) concatStringsSep concatMapStringsSep escapeNixIdentifier sanitizeDerivationName; - inherit (lib.lists) foldr foldl' concatMap elemAt all partition groupBy take foldl; + inherit (lib.lists) filter foldr foldl' concatMap elemAt all partition groupBy take foldl; in rec { @@ -644,7 +644,7 @@ rec { filterAttrs = pred: set: - removeAttrs set (concatMap (name: if pred name set.${name} then [ ] else [ name ]) (attrNames set)); + removeAttrs set (filter (name: ! pred name set.${name}) (attrNames set)); /** Filter an attribute set recursively by removing all attributes for