lib/attrsets: introduce mapCartesianProduct
This commit is contained in:
parent
10517cf9ab
commit
fe2bead78b
3 changed files with 60 additions and 1 deletions
|
@ -913,6 +913,40 @@ rec {
|
|||
) [{}] (attrNames attrsOfLists);
|
||||
|
||||
|
||||
/**
|
||||
Return the result of function f applied to the cartesian product of attribute set value combinations.
|
||||
Equivalent to using cartesianProduct followed by map.
|
||||
|
||||
# Inputs
|
||||
|
||||
`f`
|
||||
|
||||
: A function, given an attribute set, it returns a new value.
|
||||
|
||||
`attrsOfLists`
|
||||
|
||||
: Attribute set with attributes that are lists of values
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
mapCartesianProduct :: (AttrSet -> a) -> AttrSet -> [a]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.attrsets.mapCartesianProduct` usage example
|
||||
|
||||
```nix
|
||||
mapCartesianProduct ({a, b}: "${a}-${b}") { a = [ "1" "2" ]; b = [ "3" "4" ]; }
|
||||
=> [ "1-3" "1-4" "2-3" "2-4" ]
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
*/
|
||||
mapCartesianProduct = f: attrsOfLists: map f (cartesianProduct attrsOfLists);
|
||||
|
||||
/**
|
||||
Utility function that creates a `{name, value}` pair as expected by `builtins.listToAttrs`.
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ let
|
|||
recursiveUpdate matchAttrs mergeAttrsList overrideExisting showAttrPath getOutput
|
||||
getBin getLib getDev getMan chooseDevOutputs zipWithNames zip
|
||||
recurseIntoAttrs dontRecurseIntoAttrs cartesianProduct cartesianProductOfSets
|
||||
updateManyAttrsByPath;
|
||||
mapCartesianProduct updateManyAttrsByPath;
|
||||
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
||||
concatMap flatten remove findSingle findFirst any all count
|
||||
optional optionals toList range replicate partition zipListsWith zipLists
|
||||
|
|
|
@ -71,6 +71,7 @@ let
|
|||
makeIncludePath
|
||||
makeOverridable
|
||||
mapAttrs
|
||||
mapCartesianProduct
|
||||
matchAttrs
|
||||
mergeAttrs
|
||||
meta
|
||||
|
@ -1753,6 +1754,30 @@ runTests {
|
|||
];
|
||||
};
|
||||
|
||||
testMapCartesianProductOfOneSet = {
|
||||
expr = mapCartesianProduct ({a}: a * 2) { a = [ 1 2 3 ]; };
|
||||
expected = [ 2 4 6 ];
|
||||
};
|
||||
|
||||
testMapCartesianProductOfTwoSets = {
|
||||
expr = mapCartesianProduct ({a,b}: a + b) { a = [ 1 ]; b = [ 10 20 ]; };
|
||||
expected = [ 11 21 ];
|
||||
};
|
||||
|
||||
testMapCartesianProcutOfTwoSetsWithOneEmpty = {
|
||||
expr = mapCartesianProduct (x: x.a + x.b) { a = [ ]; b = [ 10 20 ]; };
|
||||
expected = [ ];
|
||||
};
|
||||
|
||||
testMapCartesianProductOfThreeSets = {
|
||||
expr = mapCartesianProduct ({a,b,c}: a + b + c) {
|
||||
a = [ 1 2 3 ];
|
||||
b = [ 10 20 30 ];
|
||||
c = [ 100 200 300 ];
|
||||
};
|
||||
expected = [ 111 211 311 121 221 321 131 231 331 112 212 312 122 222 322 132 232 332 113 213 313 123 223 323 133 233 333 ];
|
||||
};
|
||||
|
||||
# The example from the showAttrPath documentation
|
||||
testShowAttrPathExample = {
|
||||
expr = showAttrPath [ "foo" "10" "bar" ];
|
||||
|
|
Loading…
Reference in a new issue