我需要按层次排序列表,有人可以帮忙吗?该列表如下所示:
// create your list
List<Person> persons = new List<Person>();
// populate it
persons.Add(new Person("child", "father"));
persons.Add(new Person("father", "grandfather"));
persons.Add(new Person("grandfather", "grandgrandfather"));
persons.Add(new Person("grandgrandfather", null));
我想要类似的东西:
我尝试在我的classe“Person”中实现IComparable,如下所示:
public class Person : IComparable<Person>
{
public String ID { get; set; }
public String ParentID { get; set; }
public Person(String id, String pid)
{
this.ID = id;
this.ParentID = pid;
}
public Int32 CompareTo(Person right)
{
if (this.ID.Equals(right.ID))
return 0;
if (this.ParentID == null) return -1;
if (right.ParentID == null) return 1;
return this.ParentID.CompareTo(right.ID);
}
}
但它没有做到这一点...
答案 0 :(得分:5)
您需要计算层次结构中项目的部门,并按部门对列表进行排序:
如果以下是人员类:
class Person
{
public string Name {get; private set;}
public string Parent {get; private set;}
public Person(string name, string parent)
{
this.Name = name;
this.Parent = parent;
}
}
这是计算层次结构中人员的部门的方法示例。
int GetDept(List<Person> list, Person person)
{
if (person.Parent == null) return 0;
return GetDept(list, list.First(p => p.Name == person.Parent)) + 1;
}
然后该方法可用于按部门
对列表进行排序List<Person> persons = new List<Person>();
// populate it
persons.Add(new Person("child", "father"));
persons.Add(new Person("father", "grandfather"));
persons.Add(new Person("grandfather", "grandgrandfather"));
persons.Add(new Person("grandgrandfather", null));
var sorted = persons.OrderBy(p => GetDept(persons, p));
foreach(var person in sorded)
Console.WriteLine("{0} {1} {2}", person.Name, person.Parent, GetDept(persons, p))
这将打印:
grandgrandfather null 0
grandfather grandgrandfather 1
father grandfather 2
child father 3
请注意,在此示例中,dept不能有效计算,因为GetDept
方法将一次又一次地调用它,并且它还使用O(n)查找列表。所有这些都可以通过为每个人计算部门一次并存储它来改进,结合更高效的查找机制(如字典),以便获得大数据集的良好性能。
答案 1 :(得分:1)
您的问题是,如果值分散得太远,您无法确定哪个更大。例如:您的祖父和子元素将始终返回-1,因为字符串“father”始终小于字符串“grandfather”。尝试将您的人值设为常数int值,然后比较如下:
const int child = 0;
const int father = 1;
const int grandfather = 2;
const int greatgrandfather = 3;
// create your list
List<Person> persons = new List<Person>();
// populate it
persons.Add(new Person(child));
persons.Add(new Person(father));
persons.Add(new Person(grandfather));
persons.Add(new Person(grandgrandfather));
public class Person : IComparable<Person>
{
public int ID { get; set; }
public Person(int id)
{
this.ID = id;
}
public Int32 CompareTo(Person right)
{
if (this.ID == right.ID)
return 0;
if (this.ID > right.ID) return -1;
else return 1;
}
}
答案 2 :(得分:0)
您必须根据排序逻辑修改public int CompareTo(Person right)
方法的逻辑。
例如
if (this.ID == grandgrandfather &&
right.ID == grandfather) return 1;
if (this.ID == grandgrandfather &&
right.ID == child) return 1;
....... a lot more
答案 3 :(得分:0)
这是一个数据问题。您正在尝试比较字符串值,但您的数据中没有固有的东西可以提供相对关系。
我建议您将值转换为Enum,然后可以轻松比较。这是一些我没有测试过的伪代码,但它应该给你一个想法:
public class Person : IComparable<Person>
{
public enum Types: int {
None,
Child,
Father,
Grandfather,
GrandGrandFather
}
public Types ID { get; set; }
public Types ParentID { get; set; }
public Person(Types id, Types pid)
{
this.ID = id;
this.ParentID = pid;
}
public Int32 CompareTo(Person right)
{
return this.ParentID.CompareTo(right.ID);
}
}