3 вложенных группы с linq
Я пытаюсь получить 4 списка глубокой коллекции списка, 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 на основе атрибутов узла сначала по количеству страниц, затем по почтовому индексу, а затем по носителю. Затем мне нужно будет просмотреть список результатов и обработать каждую заявку в определенном порядке. У меня проблемы с получением правильного синтаксиса для 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;
2 ответа
Если ничего другого, я считаю, что этот код отвечает на ваш вопрос. Работать с четырьмя вложенными списками довольно сложно, и если вы сможете преобразовать свое решение во что-то более простое, вы, вероятно, обнаружите, что ваш код будет проще поддерживать.
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();
Я не уверен, как это сделать с 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
теряет ключ, поэтому единственный способ получить ключ (страницу, почтовый индекс или носитель) - просмотреть список вниз, что может стать уродливым и сложным. Извините, если словарь не будет работать для вас.