Получить класс и некоторые данные от его родителя в классах циклических ссылок - PullRequest
0 голосов
/ 03 ноября 2018

Пожалуйста, примите во внимание следующие коды:

public class TimeSerie
{
    public string Name { set; get; }

    public List<Data> ListData { get; set; }
}

public class Data
{
    public int Id { get; set; }
    public TimeSerie A { get; set; }
}

public class ClassC
{
    TimeSerie a;
    public ClassC()
    {
        a = new TimeSerie()
        {
            Name = "Nima",
            ListData = new List<Data>()
                {
                   new Data()
                   {
                       Id = 1 ,
                       A = new TimeSerie()
                       {
                           Name = "MyName1",
                           ListData = new List<Data>()
                           {
                               new Data() {Id= 1 },
                               new Data() {Id= 2 },
                               new Data() {Id= 3 },
                               new Data() {Id= 4 },
                           }
                       }
                   },
                   new Data() {Id= 2 },
                   new Data() {Id= 3 },
                   new Data() {Id= 4 },
                   new Data() {Id= 5 },
                   new Data() {Id= 18 },
                   new Data()
                   {
                       Id = 10,
                       A = new TimeSerie()
                       {
                           Name = "MyName2",
                           ListData = new List<Data>()
                           {
                               new Data() {Id= 5 },
                               new Data()
                               {
                                   Id = 6,
                                   A = new TimeSerie()
                                   {
                                       Name="MyName3",
                                       ListData = new List<Data>()
                                       {
                                           new Data() {Id= 20 },
                                           new Data() {Id= 2 },
                                           new Data() {Id= 7 },
                                       }
                                   }
                               },
                               new Data() {Id= 7 },
                               new Data() {Id= 8 },
                           }
                       }
                   },
                   new Data() {Id= 20 },
                   new Data() {Id= 2 },
                   new Data() {Id= 7 },
                   new Data() {Id= 20 },
                   new Data() {Id= 15 },
                }
        };
    }        
}

Я хочу получить результат List<int, TimeSerie> с int - это Id из Data, а TimeSerie - это экземпляр класса TimeSerie. Например:

 Id                       TimeSerie
 -------------------------------------------------------
 1                         new TimeSerie()
                           {
                               Name = "MyName1",
                               ListData = new List<Data>()
                               {
                                   new Data() {Id= 1 },
                                   new Data() {Id= 2 },
                                   new Data() {Id= 3 },
                                   new Data() {Id= 4 },
                               }
                           }
  -------------------------------------------------------------
  10                       new TimeSerie()
                           {
                               Name = "MyName2",
                               ListData = new List<Data>()
                               {
                                   new Data() {Id= 5 },
                                   new Data()
                                   {
                                       Id = 6,
                                       A = new TimeSerie()
                                       {
                                           Name="MyName3",
                                           ListData = new List<Data>()
                                           {
                                               new Data() {Id= 20 },
                                               new Data() {Id= 2 },
                                               new Data() {Id= 7 },
                                           }
                                       }
                                   },
                                   new Data() {Id= 7 },
                                   new Data() {Id= 8 },
                               }
                           }
----------------------------------------------------------
6                          new TimeSerie()
                           {
                               Name="MyName3",
                               ListData = new List<Data>()
                               {
                                   new Data() {Id= 20 },
                                   new Data() {Id= 2 },
                                   new Data() {Id= 7 },
                                }
                            }

Как мне достичь этого результата?

Спасибо

Ответы [ 2 ]

0 голосов
/ 03 ноября 2018

Я создал метод расширения, который использует рекурсивный метод выбора, работающий напрямую с перечислителями, см. Ссылку: IEnumerable и Recursion, использующие возвращаемый результат .

Вы можете добавить следующий метод к вашему ClassC:

public IEnumerable<TimeSerie> GetFlattenedSeries()
{
    return a.GetDeepTimeSeries();
}

позвоните по этому номеру:

ClassC c = new ClassC();
List<TimeSerie> myList = c.GetFlattenedSeries().ToList();

Добавочный код:

public static class EnumExtension
    {
        public static IEnumerable<TSource> RecursiveSelect<TSource>(this TSource source, Func<TSource, IEnumerable<TSource>> childSelector)
        {
            yield return source;
            var stack = new Stack<IEnumerator<TSource>>();
            var enumerator = childSelector(source).GetEnumerator();

            try
            {
                while (true)
                {
                    if (enumerator.MoveNext())
                    {
                        TSource element = enumerator.Current;
                        yield return element;

                        stack.Push(enumerator);
                        enumerator = childSelector(element).GetEnumerator();
                    }
                    else if (stack.Count > 0)
                    {
                        enumerator.Dispose();
                        enumerator = stack.Pop();
                    }
                    else
                    {
                        yield break;
                    }
                }
            }
            finally
            {
                enumerator.Dispose();

                while (stack.Count > 0) // Clean up in case of an exception.
                {
                    enumerator = stack.Pop();
                    enumerator.Dispose();
                }
            }
        }

        public static IEnumerable<TimeSerie> GetDeepTimeSeries(this TimeSerie serie)
        {
            return serie.RecursiveSelect<TimeSerie>(c=>c.ListData.Select(e=>e.A).Where(e=>e != null));
        }
    }
0 голосов
/ 03 ноября 2018

Вы можете сделать это с помощью рекурсии (а именно, поиск DFS):

добавьте эти вспомогательные методы к вашему ClassC:

 public List<Dictionary<int, TimeSerie>> GetTimeSeries()
            {
                var ret = new List<Dictionary<int, TimeSerie>>();

                if(a.ListData.Count != 0)
                {

                    foreach(var data in a.ListData)
                    {
                        GetRec(data, ref ret);
                    }
                }

                return ret;
            }

            private void GetRec(Data data, ref List<Dictionary<int, TimeSerie>> ret)
            {
                if(data.A != null && data.A.ListData.Count != 0)
                {
                    ret.Add(new Dictionary(data.id,data.A));
                    foreach(var d in data.A.ListData)
                    {
                        GetRec(d, ref ret);
                    }
                }   
            }

и вот пример Main метод:

 static void Main(string[] args)
        {
            ClassC c = new ClassC();
            var t = c.GetTimeSeries();
            Console.WriteLine("hello");
        }
...