3 вложенных группы с linq - PullRequest
4 голосов
/ 20 марта 2012

Я пытаюсь получить список из 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 ]

5 голосов
/ 21 марта 2012

Я не уверен, как это сделать с 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теряет ключ, поэтому единственный способ получить ключ (страницу, почтовый индекс или носитель) - просмотреть список вниз, что может стать уродливым и сложным.Извините, если у вас не работает словарь.

3 голосов
/ 21 марта 2012

Если я не верю, этот код отвечает на ваш вопрос.Работать с четырьмя вложенными списками довольно сложно, и если вы сможете преобразовать свое решение во что-то более простое, вы, вероятно, обнаружите, что ваш код будет легче поддерживать.

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...