Generate combinations of set inside set without intersection with values of current set in C# -
what (easy read , fast runtime) way of generating combinations of set (set of items) inside other set (set of groups) without intersection values of current set (items in same group)?
for example have 2 simple classes. group contains set of item
public class group { public string name { get; set; } public iset<item> items { get; set; } } public class item { public string name { get; set; } }
as result have set of groups each 1 contains set of items configured like:
var groupa = new group { name = "a", items = new hashset<item> { new item { name = "a1" }, new item { name = "a2" }, new item { name = "a3" } } }; var groupb = new group { name = "b", items = new hashset<item> { new item { name = "b1" }, new item { name = "b2" }, } }; var groupc = new group { name = "c", items = new hashset<item> { new item { name = "c1" }, new item { name = "c2" }, new item { name = "c3" }, new item { name = "c4" }, } }; var groupsset = new hashset<group>(); groupsset.add(groupa); groupsset.add(groupb); groupsset.add(groupc);
what way groupsset
combinations (1) , (2):
1)
a1, b1, c1 a1, b1, c2 a1, b1, c3 a1, b1, c4 a1, b2, c1 a1, b2, c2 a1, b2, c3 a1, b2, c4 a2, b1, c1 a2, b1, c2 a2, b1, c3 a2, b1, c4 a2, b2, c1 a2, b2, c2 a2, b2, c3 a2, b2, c4 a3, b1, c1 a3, b1, c2 a3, b1, c3 a3, b1, c4 a3, b2, c1 a3, b2, c2 a3, b2, c3 a3, b2, c4
2)
a1 a2 a3 b1 b2 c1 c2 c3 c4 a1, b1 a1, b2 a2, b1 a2, b2 a3, b1 a3, b2 a1, c1 a1, c2 a1, c3 a1, c4 a2, c1 a2, c2 a2, c3 a2, c4 a3, c1 a3, c2 a3, c3 a3, c4 b1, c1 b1, c2 b1, c3 b1, c4 b2, c1 b2, c2 b2, c3 b2, c4 a1, b1, c1 a1, b1, c2 a1, b1, c3 a1, b1, c4 a1, b2, c1 a1, b2, c2 a1, b2, c3 a1, b2, c4 a2, b1, c1 a2, b1, c2 a2, b1, c3 a2, b1, c4 a2, b2, c1 a2, b2, c2 a2, b2, c3 a2, b2, c4 a3, b1, c1 a3, b1, c2 a3, b1, c3 a3, b1, c4 a3, b2, c1 a3, b2, c2 a3, b2, c3 a3, b2, c4
when items same roup not intersected each other, items other groups?
amount of groups , amount of items in group may differ.
order of items inside combination not relevant.
thank you.
you're looking cartesian product, can generated using linq's selectmany
, or in query syntax:
var query = in groupa.items b in groupb.items c in groupc.items select new group() { items = new hashset<item>() { a, b, c }, }; var groupsset = new hashset<group>(query);
if don't know number of groups @ compile time can use this solution eric lippert cartesian product of unknown number of sequences:
public static ienumerable<ienumerable<t>> cartesianproduct<t>(this ienumerable<ienumerable<t>> sequences) { ienumerable<ienumerable<t>> emptyproduct = new[] { enumerable.empty<t>() }; return sequences.aggregate( emptyproduct, (accumulator, sequence) => accseq in accumulator item in sequence select accseq.concat(new[] { item })); }
which allows write:
var groups = new[] { groupa.items, groupb.items, groupc.items }; var query2 = groups.cartesianproduct() .select(combination => new group { items = new hashset<item>(combination), });
Comments
Post a Comment