3 nested groups with linq
本文关键字:linq with groups nested | 更新日期: 2023-09-27 18:28:30
我正在尝试获取4 List深度列表集合List<List<List<List<int>>>>
。来自我的Xml,它看起来像
<root>
<Claim key="1" carrier="carA" zip="34343" pages="1"/>
<Claim key="2" carrier="carA" zip="34343" pages="2"/>
<Claim key="3" carrier="carB" zip="10505" pages="2"/>
<Claim key="4" carrier="carB" zip="10505" pages="4"/>
<Claim key="5" carrier="carB" zip="10505" pages="4"/>
</root>
输出的结构应该看起来像
-all
-1
-34343
-carA
-1
-2
-34343
-carA
-2
-10505
-carB
-3
-4
-10505
-carB
-4
-5
目标是根据节点属性对XML进行排序,首先按页数,然后按zip,然后按carrier。然后,我需要循环浏览结果列表,并按特定顺序处理每个索赔。我在为3个嵌套组获取正确的语法时遇到了问题。我已经完成了获得两个嵌套组的任务,谁能帮我获得第三个吗。
这是我迄今为止的代码。
var query = from claim in root.Elements("Claim")
group claim by claim.Attributes("Pages").First().Value into pageGroups
from zipGroups in
(from claim in pageGroups
group claim by int.Parse(claim.Attributes("CarrierZip").First().Value))
group zipGroups by pageGroups.Key;
我不知道如何使用XML实现这一点,但如果您已经将声明转换为某种类型的Claim
的数组(例如,在代码中,claims
的类型为Claim[]
),并且Claim
类型具有名为Key
、Carrier
、Zip
和Pages
的属性或字段,那么这应该可以工作。
var dic = (from claim in claims
group claim by claim.Pages into pageGroup
select new {
Page = pageGroup.Key,
Entries =
(from zentry in pageGroup
group zentry by zentry.Zip into zipGroup
select new {
Zip = zipGroup.Key,
Entries =
(from centry in zipGroup
group centry by centry.Carrier into carrierGroup
select new { Carrier = carrierGroup.Key, Entries = carrierGroup.AsEnumerable() })
.ToDictionary(ent => ent.Carrier, ent => ent.Entries)
}).ToDictionary(ent => ent.Zip, ent => ent.Entries)
}).ToDictionary(ent => ent.Page, ent => ent.Entries);
它不是很干净,但它有效。您可以选择具有给定页面、邮政编码和承运人的索赔,如下所示:
var myclaim = dic[4][34343]["carB"];
我选择给你一种翻译成Dictionary<TKey, TValue>
而不是List<T>
的方法,因为翻译成List
会丢失密钥,所以获得密钥(页面、zip或载体)的唯一方法是向下遍历列表,这可能会变得丑陋和复杂。如果字典对你不起作用,很抱歉。
如果没有其他内容,我相信这段代码可以回答您的问题。必须处理四个嵌套列表是非常复杂的,如果你能将你的解决方案重构成更简单的东西,你可能会发现你的代码更容易维护。
var xml = @"<root>
<Claim key=""1"" carrier=""carA"" zip=""34343"" pages=""1""/>
<Claim key=""2"" carrier=""carA"" zip=""34343"" pages=""2""/>
<Claim key=""3"" carrier=""carB"" zip=""10505"" pages=""2""/>
<Claim key=""4"" carrier=""carB"" zip=""10505"" pages=""4""/>
<Claim key=""5"" carrier=""carB"" zip=""10505"" pages=""4""/>
</root>";
var xElement = XElement.Parse(xml);
var claims = xElement
.Elements("Claim")
.Select(
x => new {
Key = (Int32) x.Attribute("key"),
Carrier = (String) x.Attribute("carrier"),
Zip = (Int32) x.Attribute("zip"),
Pages = (Int32) x.Attribute("pages")
}
);
var lists = claims
.OrderBy(claim => claim.Pages)
.GroupBy(claim => claim.Pages)
.Select(pagesGroup => pagesGroup
.OrderBy(claim => claim.Zip)
.GroupBy(claim => claim.Zip)
.Select(zipGroup => zipGroup
.OrderBy(claim => claim.Carrier)
.GroupBy(claim => claim.Carrier)
.Select(carrierGroup => carrierGroup
.OrderBy(claim => claim.Key)
.Select(claim => claim.Key)
.ToList()
)
.ToList()
)
.ToList()
)
.ToList();