lib.lists: Use builtins.groupBy for lib.groupBy

builtins.groupBy is much more performant. It was introduced in
https://github.com/NixOS/nix/pull/5715
This commit is contained in:
Silvan Mosberger 2021-12-02 19:34:08 +01:00
parent 71b130c581
commit 1ad7812c4a
2 changed files with 26 additions and 9 deletions

View File

@ -4,6 +4,7 @@
let let
inherit (lib.strings) toInt; inherit (lib.strings) toInt;
inherit (lib.trivial) compare min; inherit (lib.trivial) compare min;
inherit (lib.attrsets) mapAttrs;
in in
rec { rec {
@ -340,15 +341,15 @@ rec {
groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ] groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ]
=> { true = 12; false = 3; } => { true = 12; false = 3; }
*/ */
groupBy' = op: nul: pred: lst: groupBy' = op: nul: pred: lst: mapAttrs (name: foldl op nul) (groupBy pred lst);
foldl' (r: e:
let
key = pred e;
in
r // { ${key} = op (r.${key} or nul) e; }
) {} lst;
groupBy = groupBy' (sum: e: sum ++ [e]) []; groupBy = builtins.groupBy or (
pred: foldl' (r: e:
let
key = pred e;
in
r // { ${key} = (r.${key} or []) ++ [e]; }
) {});
/* Merges two lists of the same size together. If the sizes aren't the same /* Merges two lists of the same size together. If the sizes aren't the same
the merging stops at the shortest. How both lists are merged is defined the merging stops at the shortest. How both lists are merged is defined

View File

@ -781,6 +781,22 @@ runTests {
"a2-b" "a2-b"
"_bc'de" "_bc'de"
]; ];
expected = "\".\".foo.\"2\".a2-b._bc'de"; expected = ''".".foo."2".a2-b._bc'de'';
};
testGroupBy = {
expr = groupBy (n: toString (mod n 5)) (range 0 16);
expected = {
"0" = [ 0 5 10 15 ];
"1" = [ 1 6 11 16 ];
"2" = [ 2 7 12 ];
"3" = [ 3 8 13 ];
"4" = [ 4 9 14 ];
};
};
testGroupBy' = {
expr = groupBy' builtins.add 0 (x: boolToString (x > 2)) [ 5 1 2 3 4 ];
expected = { false = 3; true = 12; };
}; };
} }