使用自定义IComparer按指针值排序

时间:2016-10-05 21:31:00

标签: c# linq

我有一个定义学生的课程,并且有一个紧接着该学生的属性(FollowedBy)。我正在寻找一种基于这种联系来订购学生的方法。

class Student
{
     public int StudentID { get; set; }   
     public string Name { get; set; }
     public int? FollowedBy { get; set; }
}

var lstStudents = new List<Student>()
{ new Student() { StudentID = 2, Name = "Mark", FollowedBy =4 },
 new Student() { StudentID = 1, Name = "Sam", FollowedBy = 2},
 new Student() { StudentID = 4, Name = "Fred", FollowedBy =null } ,
 new Student() { StudentID = 3, Name = "Janice", FollowedBy = 1}};

  for (var s in     lstStudents.OrderBy(x => ????))
  {
         console.Write(s.Name);
  }

 // The output I'm looking for
 //  Janice
 //  Sam
 //  Mark
 //  Fred

3 个答案:

答案 0 :(得分:2)

您尝试做的不是严格排序,并且它不支持依赖于IComparer等比较原则的某些排序算法,而不会使IComparer的实现意识到整个组。这样的FollowedBy可能比使用搜索简单排序要慢得多。

似乎更容易将其变成一个辅助方法(扩展方法,如果你想使用类似linq的语法),它使用自己的机制来搜索每个StudentID / {{的集合1}}组合。

答案 1 :(得分:2)

    public List<Student> GetOrderedStudents(List<Student> students)
    {
        Student[] reverseOrder = new Student[students.Count];

        Student last = students.Single(s => s.FollowedBy == null);

        reverseOrder[0] = last;
        Student next = last;

        for (var i = 1; i < students.Count; i++)
        {
            next = students.Single(s => s.FollowedBy == next.StudentID);
            reverseOrder[i] = next;
        }

        return reverseOrder.Reverse().ToList();  
    }

答案 2 :(得分:2)

您可以找到根,然后关注FollowedBy

  Dictionary<int, Student> dict = lstStudents
    .ToDictionary(item => item.StudentID);

  // root
  Student s = dict[lstStudents
    .Select(item => item.StudentID)
    .Except(lstStudents
       .Where(item => item.FollowedBy.HasValue)
       .Select(item => item.FollowedBy.Value))
    .First()];

  for (; s != null; s = s.FollowedBy == null? null : dict[s.FollowedBy.Value]) {
    Console.WriteLine(s.Name);
  }