分组限制每组的项目

时间:2013-12-09 10:58:06

标签: c# .net linq lambda linq-to-xml

我有以下XML:

<R N="1">
  <MT N="Section" V="Section-1" />
  <MT N="Person" V="John" />
</R>
<R N="2">
  <MT N="Section" V="Section-1" />
  <MT N="Person" V="Peter" />
</R>
<R N="3">
  <MT N="Section" V="Section-2" />
  <MT N="Person" V="Joseph" />
</R>
... ...

<R N="N">
  <MT N="Section" V="Section-J" />
  <MT N="Person" V="PersonX" />
</R>

以下生成GroupBy的{​​{1}}子句:

IEnumerable<IGrouping<string,XElement>>

我希望每组最多有4个项目。

我无法在var something = MyElements.GroupBy ( x => x.Elements("MT") .First ( type => type.Attribute("N").Value == "Section" ) .Attribute("V").Value , x=>x ); 表达式上使用Take方法,因为它不是x=>x

您知道如何限制每组的结果吗?

2 个答案:

答案 0 :(得分:2)

如果你想要的只是一个IEnumerable<IEnumerable<XElement>>

,你可以使用这样的Take
var something = MyElements.GroupBy
(
   x => x.Elements("MT")
   .First
   (
       type => type.Attribute("N").Value == "Section"
   )
   .Attribute("V").Value
   ,
   x => x,
   (Key, Items) => Items.Take(4)
);

如果您还需要密钥,可以执行以下操作:

var something = MyElements.GroupBy
(
   x => x.Elements("MT")
   .First
   (
       type => type.Attribute("N").Value == "Section"
   )
   .Attribute("V").Value
   ,
   x => x,
   (Key, Items) => new { Key, Items = g.Take(4) }
);

虽然,您将获得IEnumerable匿名类型。您需要遍历Items集合。如果您不能使用匿名类型(例如,您需要将其作为方法签名的一部分),您可以始终创建自己的结果类型或使用Tuple

答案 1 :(得分:1)

我相信你可以使用以下声明性查询来获得你需要的东西

var xdoc = XDocument.Load(path_to_xml);
var query = from r in xdoc.Descendants("R")
            let section = r.Elements("MT")
                           .First(mt => (string)mt.Attribute("N") == "Section")
                           .Attribute("V")
            group r by (string)section into g
            select g.Take(4);