Member 13503622 Ответов: 2

C#- у меня есть строка с древовидной структурой , я должен сгруппировать одних и тех же родителей вместе и реструктурировать строку.


Мне нужно решение для нижеприведенной проблемы в C#/LINQ, где я должен преобразовать нижеприведенную строку inout в выходную строку.

входная строка -
App.MName, App.LName, CoApp.Lname В, CoApp.CurrRes.Адрес, Вэх.Год , LS.TotalAmount, TrdIn.Year

Ожидаемая Выходная Строка -
Приложение(MName,lname в..),CoApp(lname в, CurrRes(адреса,..),..),а / м(год,..),Общ(TotaAmount,..), TrdIn(год)

В основном группировка родителя вместе, чтобы избежать повторения имен.

Что я уже пробовал:

Я пробовал различные строковые функции , однако мне было трудно вложить один родитель в другой.

PIEBALDconsult

Разрежьте его на куски в XmlDocument,а затем снова разрежьте обратно?

Karthik_Mahalingam

каково максимальное число иерархий "родитель-потомок"?
пример: CoApp.CurrRes.Адрес - 3

Member 13503622

5

Karthik_Mahalingam

ладно.

PIEBALDconsult

Я иду без ограничений.

Karthik_Mahalingam

правильно, это будет общий язык
кажется хитрым :)

PIEBALDconsult

Кажется, это проще, чем устанавливать произвольные ограничения.

2 Ответов

Рейтинг:
13

Graeme_Grant

Немного поздно но вот компактное решение LINQ:

class Program
{
    static void Main(string[] args)
    {
        var input = "App.MName, App.LName, CoApp.xxx.yyy.zzz, CoApp.LName, CoApp.CurrRes.Address, CoApp.CurrRes.Address.SubAddress1, CoApp.CurrRes.Address.SubAddress2, Veh.Year , LS.TotalAmount, TrdIn.Year";

        var result = string.Join(",", input.Split(new[] { ',', ' ' },
                                 StringSplitOptions.RemoveEmptyEntries)
                           .Select(x => x.Split(new[] { '.' }).ToList())
                           .GroupBy(y => y[0])
                           .Select(x => CustomGroup(x)));

        Console.WriteLine(input);
        Console.WriteLine();
        Console.WriteLine(result);
        Console.ReadKey();
    }

    private static string CustomGroup(IGrouping<string, IEnumerable<string>> group)
    {
        var items = group.Where(x => x.Skip(1).Any());
        return items.Any() 
            ? new StringBuilder()
                .Append(group.Key)
                .Append("(")
                .Append(string.Join(",", items.Select(x => x.Skip(1))
                                                .GroupBy(y => y.First())
                                                .Select(x => CustomGroup(x))))
                .Append(")")
                .ToString() 
            : group.Key;
    }
}

Выходы:
App.MName, App.LName, CoApp.xxx.yyy.zzz, CoApp.LName, CoApp.CurrRes.Address, CoApp.CurrRes.Address.SubAddress1, CoApp.CurrRes.Address.SubAddress2, Veh.Year , LS.TotalAmount, TrdIn.Year

App(MName,LName),CoApp(xxx(yyy(zzz)),LName,CurrRes(Address(SubAddress1,SubAddress2))),Veh(Year),LS(TotalAmount),TrdIn(Year)


Karthik_Mahalingam

5!

Рейтинг:
12

PIEBALDconsult

namespace Foo
{
  public static partial class Bar
  {
    private static readonly System.Text.RegularExpressions.Regex reg ;

    static Bar
    (
    )
    {
      reg = new System.Text.RegularExpressions.Regex
      (
        @"(\w+)(?:\.(\w+)*)*"
      ,
        System.Text.RegularExpressions.RegexOptions.Compiled
      ) ;

      return ;
    }

    public static string
    Baz
    (
      string Input
    )
    {
      System.Text.StringBuilder result = new System.Text.StringBuilder ( Input.Length ) ;

      System.Text.RegularExpressions.MatchCollection mc = reg.Matches ( Input ) ;

      System.Xml.XmlDocument doc = new System.Xml.XmlDocument() ;

      System.Xml.XmlNode ele = doc.CreateElement ( "Hierarchy" ) ;

      doc.AppendChild ( ele ) ;

      for ( int i = 0 ; i < mc.Count ; i++ )
      {
        ele = doc.DocumentElement ;

        for ( int j = 1 ; j < mc [ i ].Groups.Count ; j++ )
        {
          for ( int k = 0 ; k < mc [ i ].Groups [ j ].Captures.Count ; k++ )
          {
            string val = mc [ i ].Groups [ j ].Captures [ k ].Value ;

            System.Xml.XmlNode tmp = ele.SelectSingleNode ( val ) ;

            if ( tmp == null )
            {
              tmp = doc.CreateElement ( val ) ;

              ele.AppendChild ( tmp ) ;
            }

            ele = tmp ;
          }
        }
      }

      Foz ( doc.DocumentElement.ChildNodes , result ) ;

      return ( result.ToString() ) ;
    }

    private static void
    Foz
    (
      System.Xml.XmlNodeList    Node
    ,
      System.Text.StringBuilder Output
    )
    {
      for ( int i = 0 ; i < Node.Count ; i++ )
      {
        Output.Append ( Node [ i ].Name ) ;

        if ( Node [ i ].HasChildNodes )
        {
          Output.Append ( "(" ) ;

          Foz ( Node [ i ].ChildNodes , Output ) ;

          Output.Append ( ")" ) ;
        }

        Output.Append ( "," ) ;
      }

      Output.Length-- ;

      return ;
    }
  }
}


System.Console.WriteLine ( Foo.Bar.Baz ( @"App.MName, App.LName, CoApp.LName, CoApp.CurrRes.Address, Veh.Year , LS.TotalAmount, TrdIn.Year" ) ) ;

App(MName,LName),CoApp(LName,CurrRes(Address)),Veh(Year),LS(TotalAmount),TrdIn(Year)


Karthik_Mahalingam

Дай Пять !!!

блестящий

PIEBALDconsult

Спасибо.

Graeme_Grant

Близко, но не линк... Версия Linq ниже.. ;)

PIEBALDconsult

Линк-это грязь.

Graeme_Grant

LMAO... Красота находится в глазах смотрящего, но в вашем случае у вас есть случай смотрел[^]... ;)

PIEBALDconsult

Я думаю, что мой будет компилироваться в любой версии C# / .net-мне придется попробовать.
(О, мне придется удалить частичное для v1. Ничего страшного.)

Graeme_Grant

Это было бы здорово, если бы мы жили в 2005 году...

Richard Deeming

Вам также придется удалить static начиная с объявления класса, так как статические классы были введены в C# 2. :)

Говоря о "грязи", ваш стиль форматирования кода просто заставил меня немного блевать. Вам платит Лок? Я не могу понять, почему еще у вас было бы так много лишних разрывов строк. :Д

Member 13503622

Большое спасибо вам обоим !!

Graeme_Grant

Я думал, что ему нужно решение LINQ (4 3 строки) ... смотреть ниже... ;)