lib/attrsets: add cartesianProductOfSets function
This commit is contained in:
parent
d9353519d7
commit
123045a570
4 changed files with 125 additions and 2 deletions
|
@ -1711,4 +1711,43 @@ recursiveUpdate
|
|||
</example>
|
||||
</section>
|
||||
|
||||
<section xml:id="function-library-lib.attrsets.cartesianProductOfSets">
|
||||
<title><function>lib.attrsets.cartesianProductOfSets</function></title>
|
||||
|
||||
<subtitle><literal>cartesianProductOfSets :: AttrSet -> [ AttrSet ]</literal>
|
||||
</subtitle>
|
||||
|
||||
<xi:include href="./locations.xml" xpointer="lib.attrsets.cartesianProductOfSets" />
|
||||
|
||||
<para>
|
||||
Return the cartesian product of attribute set value combinations.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<varname>set</varname>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>
|
||||
An attribute set with attributes that carry lists of values.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<example xml:id="function-library-lib.attrsets.cartesianProductOfSets-example">
|
||||
<title>Creating the cartesian product of a list of attribute values</title>
|
||||
<programlisting><![CDATA[
|
||||
cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; }
|
||||
=> [
|
||||
{ a = 1; b = 10; }
|
||||
{ a = 1; b = 20; }
|
||||
{ a = 2; b = 10; }
|
||||
{ a = 2; b = 20; }
|
||||
]
|
||||
]]></programlisting>
|
||||
</example>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
|
|
@ -183,6 +183,24 @@ rec {
|
|||
else
|
||||
[];
|
||||
|
||||
/* Return the cartesian product of attribute set value combinations.
|
||||
|
||||
Example:
|
||||
cartesianProductOfSets { a = [ 1 2 ]; b = [ 10 20 ]; }
|
||||
=> [
|
||||
{ a = 1; b = 10; }
|
||||
{ a = 1; b = 20; }
|
||||
{ a = 2; b = 10; }
|
||||
{ a = 2; b = 20; }
|
||||
]
|
||||
*/
|
||||
cartesianProductOfSets = attrsOfLists:
|
||||
lib.foldl' (listOfAttrs: attrName:
|
||||
concatMap (attrs:
|
||||
map (listValue: attrs // { ${attrName} = listValue; }) attrsOfLists.${attrName}
|
||||
) listOfAttrs
|
||||
) [{}] (attrNames attrsOfLists);
|
||||
|
||||
|
||||
/* Utility function that creates a {name, value} pair as expected by
|
||||
builtins.listToAttrs.
|
||||
|
@ -493,5 +511,4 @@ rec {
|
|||
zipWithNames = zipAttrsWithNames;
|
||||
zip = builtins.trace
|
||||
"lib.zip is deprecated, use lib.zipAttrsWith instead" zipAttrsWith;
|
||||
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ let
|
|||
zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil
|
||||
recursiveUpdate matchAttrs overrideExisting getOutput getBin
|
||||
getLib getDev getMan chooseDevOutputs zipWithNames zip
|
||||
recurseIntoAttrs dontRecurseIntoAttrs;
|
||||
recurseIntoAttrs dontRecurseIntoAttrs cartesianProductOfSets;
|
||||
inherit (self.lists) singleton forEach foldr fold foldl foldl' imap0 imap1
|
||||
concatMap flatten remove findSingle findFirst any all count
|
||||
optional optionals toList range partition zipListsWith zipLists
|
||||
|
|
|
@ -660,4 +660,71 @@ runTests {
|
|||
expected = [ [ "foo" ] [ "foo" "<name>" "bar" ] [ "foo" "bar" ] ];
|
||||
};
|
||||
|
||||
testCartesianProductOfEmptySet = {
|
||||
expr = cartesianProductOfSets {};
|
||||
expected = [ {} ];
|
||||
};
|
||||
|
||||
testCartesianProductOfOneSet = {
|
||||
expr = cartesianProductOfSets { a = [ 1 2 3 ]; };
|
||||
expected = [ { a = 1; } { a = 2; } { a = 3; } ];
|
||||
};
|
||||
|
||||
testCartesianProductOfTwoSets = {
|
||||
expr = cartesianProductOfSets { a = [ 1 ]; b = [ 10 20 ]; };
|
||||
expected = [
|
||||
{ a = 1; b = 10; }
|
||||
{ a = 1; b = 20; }
|
||||
];
|
||||
};
|
||||
|
||||
testCartesianProductOfTwoSetsWithOneEmpty = {
|
||||
expr = cartesianProductOfSets { a = [ ]; b = [ 10 20 ]; };
|
||||
expected = [ ];
|
||||
};
|
||||
|
||||
testCartesianProductOfThreeSets = {
|
||||
expr = cartesianProductOfSets {
|
||||
a = [ 1 2 3 ];
|
||||
b = [ 10 20 30 ];
|
||||
c = [ 100 200 300 ];
|
||||
};
|
||||
expected = [
|
||||
{ a = 1; b = 10; c = 100; }
|
||||
{ a = 1; b = 10; c = 200; }
|
||||
{ a = 1; b = 10; c = 300; }
|
||||
|
||||
{ a = 1; b = 20; c = 100; }
|
||||
{ a = 1; b = 20; c = 200; }
|
||||
{ a = 1; b = 20; c = 300; }
|
||||
|
||||
{ a = 1; b = 30; c = 100; }
|
||||
{ a = 1; b = 30; c = 200; }
|
||||
{ a = 1; b = 30; c = 300; }
|
||||
|
||||
{ a = 2; b = 10; c = 100; }
|
||||
{ a = 2; b = 10; c = 200; }
|
||||
{ a = 2; b = 10; c = 300; }
|
||||
|
||||
{ a = 2; b = 20; c = 100; }
|
||||
{ a = 2; b = 20; c = 200; }
|
||||
{ a = 2; b = 20; c = 300; }
|
||||
|
||||
{ a = 2; b = 30; c = 100; }
|
||||
{ a = 2; b = 30; c = 200; }
|
||||
{ a = 2; b = 30; c = 300; }
|
||||
|
||||
{ a = 3; b = 10; c = 100; }
|
||||
{ a = 3; b = 10; c = 200; }
|
||||
{ a = 3; b = 10; c = 300; }
|
||||
|
||||
{ a = 3; b = 20; c = 100; }
|
||||
{ a = 3; b = 20; c = 200; }
|
||||
{ a = 3; b = 20; c = 300; }
|
||||
|
||||
{ a = 3; b = 30; c = 100; }
|
||||
{ a = 3; b = 30; c = 200; }
|
||||
{ a = 3; b = 30; c = 300; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue