-1

什么是在其他集合(组集合)内生成集合(项目集合)组合而不与当前集合(同一组中的项目)的值相交的好(易于阅读和快速运行)方法?

例如,我有两个简单的类。包含一组项目的组

public class Group
{
    public string Name { get; set; }
    public ISet<Item> Items { get; set; }
}

public class Item
{
    public string Name { get; set; }
}

结果,我有一组组,每个组包含一组配置为:

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);

groupsSet从(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

当同一组中的项目不相互交叉时,仅与其他组中的项目相交?

组的数量和组中的项目数量可能不同。

组合内的项目顺序不相关。

谢谢你。

4

2 回答 2

2

您正在寻找笛卡尔积,它可以简单地使用 LINQSelectMany或查询语法生成:

var query = from a in groupA.Items
            from b in groupB.Items
            from c in groupC.Items
            select new Group()
            {
                Items = new HashSet<Item>() { a, b, c },
            };



var groupsSet = new HashSet<Group>(query);

如果您在编译时不知道组的数量,您可以使用Eric Lippert 的这个解决方案来获得未知数量序列的笛卡尔积:

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) =>
        from accseq in accumulator
        from item in sequence
        select accseq.Concat(new[] { item }));
}

它允许您编写:

var groups = new[] { groupA.Items, groupB.Items, groupC.Items };

var query2 = groups.CartesianProduct()
    .Select(combination => new Group
    {
        Items = new HashSet<Item>(combination),
    });
于 2013-09-03T19:33:55.957 回答
0

您只是在寻找笛卡尔积吗?

您可以尝试这样的加入:

var product = 
    (from first in groupA 
    from second in groupB 
    from third in groupC             
    select new Group()
        {
            Items = new HashSet<Item>() { a, b, c },
        });
于 2013-09-03T19:31:05.887 回答