在循环引用 classes 中从它的父级获取 class 和一些数据
Get a class and some data from it's parent in circular reference classes
请考虑以下代码:
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
是 Data
的 Id
,TimeSerie
是 TimeSerie
的实例 class。例如:
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 },
}
}
我怎样才能达到这个结果?
谢谢
你可以用递归来做(即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");
}
我创建了一个扩展方法,它使用递归 select 直接与枚举器一起工作,请参阅 link:IEnumerable and Recursion using yield return。
您可以将以下方法添加到您的 ClassC 中:
public IEnumerable<TimeSerie> GetFlattenedSeries()
{
return a.GetDeepTimeSeries();
}
调用它:
ClassC c = new ClassC();
List<TimeSerie> myList = c.GetFlattenedSeries().ToList();
分机号:[=14=]
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));
}
}
请考虑以下代码:
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
是 Data
的 Id
,TimeSerie
是 TimeSerie
的实例 class。例如:
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 },
}
}
我怎样才能达到这个结果?
谢谢
你可以用递归来做(即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");
}
我创建了一个扩展方法,它使用递归 select 直接与枚举器一起工作,请参阅 link:IEnumerable and Recursion using yield return。
您可以将以下方法添加到您的 ClassC 中:
public IEnumerable<TimeSerie> GetFlattenedSeries()
{
return a.GetDeepTimeSeries();
}
调用它:
ClassC c = new ClassC();
List<TimeSerie> myList = c.GetFlattenedSeries().ToList();
分机号:[=14=]
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));
}
}