在LINQ中集合按子元素的简单方法?

时间:2011-11-11 14:55:54

标签: c# linq

我对可枚举的正常GroupBy操作:

e.GroupBy(i => i.Property)

但是如果i.Property真的是一个集合,我如何分解集合并使用列表的元素作为分组键?

例如,假设我有两个对象(Z,Y),每个对象都有一个列表:

Z: { List = { A, B, C }}
Y: { List = { B, C, D }}

现在运行GroupBySubelement(o => o.List)不会按列表本身进行分组,但会迭代列表并生成以下分组。

{A, {Z}}
{B, {Z, Y}}
{C, {Z, Y}}
{D, {Y}

这可能吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

以下是一些实现您想要的示例代码:

//This is just temporary data.  Has the similar structure to what you want.
var parts = new[]
                {
                    new
                        {
                            Name = "X",
                            Property = new[] {'A', 'B', 'C'}
                        },
                    new
                        {
                            Name = "Y",
                            Property = new[] {'B', 'C', 'D'}
                        },
                    new
                        {
                            Name = "Z",
                            Property = new char[] { }
                        }
                    };

var groupedBySub = from part in parts
                   from sub in part.Property
                   group part by sub;

foreach(var group in groupedBySub)
{
    Console.WriteLine("{0} - {1}", group.Key, string.Join(", ", group.Select(x => x.Name)));
}

哪个输出:

A - X
B - X, Y
C - X, Y
D - Y

您也可以通过方法链方式实现这一目标:

var groupedBySub = parts.SelectMany(part => part.Property, (part, sub) => new {part, sub}).GroupBy(t => t.sub,  t => t.part);

如果要在列表为空的情况下捕获它:

var groupedBySub = from part in parts
                   from sub in part.Property.DefaultIfEmpty()
                   group part by sub;

当替换上面的代码时,给出输出:

A - X
B - X, Y
C - X, Y
D - Y
  - Z

答案 1 :(得分:0)

这样做:

var combinations = e.SelectMany(i => i.List.Select(x => new { x, i }));
var groups = combinations.GroupBy(c => c.x, c => c.i);

答案 2 :(得分:-1)

这里的部分问题是你没有一个好的数据结构:

var z = new List<T>(); // I'm using T here, so let's pretend this is in a generic method
var y = new List<T>();
// add a bunch of stuff

实际上没有任何算法能够满足您的需求,因为数据结构并不是真正知道变量Z和Y,而只是编译器。

但是如果你有这样的数据结构怎么办:

var allOfTheLists = new Dictionary<T, List<T>>();

然后您可以使用以下内容将其分解:

var explodedList = allOfTheLists.SelectMany((pair) => pair.Value.Select((item) => new { pair.Key, item}));
var grouping = explodedList.GroupBy((explodedItem) => explodedItem.item);