我有以下结构:
class Employee
{
public long Id { get; set; }
public long? ParentId { get; set; }
public Employee(long id, long? parentId)
{
Id = id;
Parent_Id = parentId;
}
}
让我们构建一些树结构:
var employees = new List<Employee>();
employees.Add(new Employee(1 , null));
employees.Add(new Employee(2 , 1));
employees.Add(new Employee(3 , 2));
如果Id
= 1的员工是此列表中Id
= 3的员工的父母,那么如何检查(使用C#)?树结构可能要复杂得多。
答案 0 :(得分:2)
要检查是否是后代,您可以遍历树并查看是否找到了他:
static bool GetIsDescendant(long idChild, long idAncestor, IEnumerable<Employee> employees)
{
return GetAncestors(idChild, employees).Any(t => t.Id == idAncestor);
}
static IEnumerable<Employee> GetAncestors(long idEmployee, IEnumerable<Employee> employees)
{
var employee = employees.SingleOrDefault(e => e.Id == idEmployee);
if (employee == null)
{
yield break;
}
while (employee.ParentId.HasValue)
{
var parent = employees.SingleOrDefault(e => e.Id == employee.ParentId.Value);
if (parent == null)
{
yield break;
}
else
{
employee = parent;
yield return parent;
}
}
}
答案 1 :(得分:1)
你可以这样做:
static bool IsParent(
IEnumerable<Employee> employees, long potentialParentId, long potentialChildId)
{
var potentialChild = employees.SingleOrDefault(e => e.Id == potentialChildId);
return potentialChild != null && potentialChild.ParentId == potentialParentId;
}
但这样做可能会非常缓慢,特别是如果你有很多员工的话。如果您想快速通过Id
进行查找,可以使用Dictionary<long, Employee>
。
答案 2 :(得分:1)
当处理对象模型中的树时,如果对象具有Children,我发现它更有用。虽然现在更容易维护父母。实际上,您可以将树抽象为通用接口,或两个:
public interface IHaveChildren<out T> where T:IHaveChildren<T>
{
/// <summary>Gets the children.</summary>
IEnumerable<T> Children { get; }
}
public interface IHaveFamily<out T> : IHaveChildren<T> where T : IHaveChildren<T>
{
/// <summary>Gets the Parent.</summary>
T Parent { get; }
}
现在,您可以设置许多有趣且有用的扩展来获取树信息,而不会让您的贫困员工类也不必担心!以下是两个利用这些接口的扩展。
public static class HeirarchyExtensions
{
public static bool IsAncestorOf<T>(this IHaveFamily<T> instance1, IHaveFamily<T> instance2) where T : IHaveFamily<T>
{
if(instance1.IsLeaf()) return false;
foreach (var child in instance1.Children)
{
if (child.Equals(instance2)) return true;
return instance1.IsAncestorOf(child);
}
return false;
}
public static IEnumerable<T> GetDescendents<T>(this IHaveFamily<T> instance) where T : IHaveFamily<T>
{
var result = instance.Children;
if(!result.Any())
return result;
foreach (var child in instance.Children) {
result = result.Concat(child.Children);
}
return result;
}
}
HTH,
Berryl