如何对这些XDocuments进行分组?

时间:2009-07-24 18:43:51

标签: c# linq-to-xml grouping

问题

我有一组XDocument个实例。每个文档都有一个重复元素,可以采用不同的值。我希望按此值对它们进行分组,但每个元素都可以指定不同的值。

<sampledoc>
  <value>a</value>
  <value>b</value>
  <value>c</value>
</sampledoc>

实施例

  • 文档A的值为a,b,c
  • 文件B的值为b,c,d
  • 文档C的值为a,b

我想要一个分组:

  • 组a
    • 文件A
    • 文件C
  • 组b
    • 文件A
    • 文件B
    • 文件C
  • 组c
    • 文件A
    • 文件B
  • 组d
    • 文件B

问题

我确信我必须能够做到这一点,但我现在看不到树木了。

docs.GroupBy...将无法自行运行(据我所知),因为它所采用的表达式应该返回一个值,每个文档可以包含多个值。我的头说单个LINQ查询应该是可能的,但它无法理解它会是什么。

可以使用GroupByAsLookup LINQ方法完成吗?有没有办法做到这一点?

我更喜欢C#中的例子,如果有人愿意提供一个。

更新

感谢Pavel Minaev的回答和一些灵感,我解决了以下问题:

// Collate all the different values
docs.SelectMany(doc => doc.Elements("Value")
                          .Select(el => el.Value))
    // Remove duplicate values
    .Distinct()
    // Generate a lookup of specific value to all
    // documents that contain that value
    .ToLookup(v => v, v => docs.Where(doc => doc.Elements("Value")
                                                .Any(el=>el.Value == v)));

1 个答案:

答案 0 :(得分:3)

GroupBy无论如何都不会帮助你,因为它会将序列中的每个元素分配给一个组。

var docs = new XDocument[] { docA, docB, docC } ;
var result = docs
   .SelectMany(doc => doc.Root.Elements("Value"))
   .Select(el => el.Value)
   .Distinct()
   .Select(key => new {
        Key = key,
        Documents = docs.Where(doc =>
            doc.Root.Elements("Value").Any(el => el.Value == key))
   });