【发布时间】:2017-08-01 22:26:17
【问题描述】:
我有一个看起来像这样的类:
public class SourceObject
{
public string Id { get; set; }
public List<SourceObject> Children { get; set; }
public SourceObject()
{
Children = new List<SourceObject>();
}
}
如您所见,它有一个属性,其中包含同一类的更多实例列表。我正在为此类处理的数据意味着子级的数量在运行时之前是未知的,并且生成的对象图的整体“深度”也是未知的。
我需要创建一个从SourceObject 的对象图到DestinationObject 的类似形状图的“映射”(类似于 AutoMapper 从一个对象映射到另一个对象的方式)。
我有一个方法可以从我的源图映射到我的目标图,但是,这个方法使用递归:
// Recursive way of mapping each Source object to Destination
public static DestinationObject MapSourceToDestination(SourceObject source)
{
var result = new DestinationObject();
result.Id = source.Id;
result.Children = source.Children.Select(MapSourceToDestination).ToList();
return result;
}
当源对象图的大小不太大或不太深时,这可以正常工作,但是,当源对象图非常大时,此方法会抛出 StackOverflow 异常。
我已经设法创建了这个函数的替代版本,它使用类似于this answer 中描述的技术来删除递归并用队列/堆栈替换它)但是,我注意到队列/堆栈可以也变得非常大,我不确定我的实现是最有效的。
是否可以将递归函数转换为仅在源对象图上使用迭代的函数(即删除递归,理想情况下,使用队列/堆栈)?
【问题讨论】:
-
是的,你可以,但你必须重新扫描整个事情多次......例如,如果你有 1、2、3 和 1 取决于 2 取决于 3,你可以这样做: 1(有未解决的依赖,暂时跳过),2(有未解决的依赖,暂时跳过),3(解决),然后返回1(仍有未解决的依赖,暂时跳过),2(解决),返回1 (解决)
-
类似this?
-
@IvanStoev 这使用了一个Stack,所以它反对理想情况下,使用队列/堆栈
-
@IvanStoev OP 要求没有堆栈的解决方案。
-
@Evk 我知道(尽管他说 ideally)。但该解决方案与 Eric 的实现不同,堆栈大小纯粹是树的深度,而 IMO 是最优的。不过,用纯迭代解决方案祝 OP 好运:)
标签: c# linq recursion iteration