简体   繁体   English

在C#中对对象列表进行排序的算法

[英]Algorithm for sorting a list of objects in c#

I have a list of object I wish to sort in C#.Net 3.5, the object is as follows 我有一个要在C#.Net 3.5中排序的对象列表,该对象如下

id | id | name | 名称| parent_id parent_id

1 | 1 | Superman | 超人| NULL 空值

2 | 2 | Batman | 蝙蝠侠 3 3

3 | 3 | Watchman | 守望人| 1 1个

4 | 4 | Wolverine | 金刚狼| 2 2

I know some of you might find this easy, but I need to sort the list based on the parent_id, which is pointing to its own index(id) in the same table. 我知道有些人可能会发现这很容易,但是我需要根据parent_id对该列表进行排序,后者指向同一表中其自己的index(id)。

So can someone give me a good algorithm to sort this list without looping over and over again? 因此,有人可以给我一个很好的算法来对列表进行排序,而不必一遍又一遍地循环吗? I cannot really phrase it that well, therefore I can't seem to google the right results I wanted. 我无法说出这么好,因此我似乎无法在Google上找到想要的正确结果。

A collection of IEnumerable or DataTable solution would be great. IEnumerable或DataTable解决方案的集合会很棒。

Thanks in advance. 提前致谢。

EDIT:----------------NEW Example 编辑:---------------- NEW示例

id | id | name | 名称| parent_id parent_id

1 | 1 | TOP CHILD | 儿童| NULL 空值

2 | 2 | Child C | 儿童C | 3 3

3 | 3 | Child B | 儿童B | 4 4

4 | 4 | Child A | 子A | 1 1个

----> The Output I want is ---->我想要的输出是

id | id | name | 名称| parent_id parent_id

1 | 1 | TOP CHILD | 儿童| NULL 空值

4 | 4 | Child A | 子A | 1 1个

3 | 3 | Child B | 儿童B | 4 4

2 | 2 | Child C | 儿童C | 3 3

----> If I use OrderBy or Sort, the result I get is ---->如果我使用OrderBy或Sort,得到的结果是

id | id | name | 名称| parent_id parent_id

1 | 1 | TOP CHILD | 儿童| NULL 空值

4 | 4 | Child A | 子A | 1 1个

2 | 2 | Child C | 儿童C | 3 3

3 | 3 | Child B | 儿童B | 4 4

--> Non of the solutions is what I really wanted, Sorry again for not being clear ->非解决方案不是我真正想要的,再次抱歉,不清楚

Hope this example is clearer 希望这个例子更清楚

You can create a class for the above data with id, name, parent_id as class members. 您可以为上述数据创建一个类,以id,name,parent_id作为类成员。 Override the CompareTo method of IComparable 重写IComparable的CompareTo方法

    public class Person : IComparable<Person>
        {
            public int id, parentID;
            public string name;

            public Person(int id, string name, int parentID)
            {
                this.id = id;
                this.name = name;
                this.parentID = parentID;
            }

            #region IComparable Members

            public int CompareTo(Person obj)
        {
        return this.parentID.CompareTo(obj.parentID);

        //OR 
        //if (this.parentID > obj.parentID)
        //{
        //    return 1;
        //}
        //else if (this.parentID < obj.parentID)
        //{
        //    return -1;
        //}

        //return 0;
        }        
            #endregion
        }

In the main code: 在主代码中:

List<Person> peopleArray = new List<Person>();
            peopleArray.Add(new Person(1, "Jerry", 1));
        peopleArray.Add(new Person(2, "George", 4));
        peopleArray.Add(new Person(3, "Elaine", 3));
        peopleArray.Add(new Person(4, "Kramer", 2));    
            peopleArray.Sort();

            foreach (Person p in peopleArray)
                Console.WriteLine(p.parentID);

This will sort the list by parent id O/P of parent ids: 1 2 3 4 这将按父ID的父ID O / P对列表进行排序:1 2 3 4

after you edit: I think I get you and the comparer looks like: 编辑后:我想得到您,比较器如下所示:

public Int32 CompareTo(SuperHero right)
{
    if (this.ID == right.ID)
        return 0;

    return this.ParentID.CompareTo(right.ID);
}

in response to your comment: 回应您的评论:

The class looks like: 该类如下所示:

public class SuperHero : IComparable<SuperHero>
{
    public Int32 ID { get; set; }
    public String Name { get; set; }
    public Int32 ParentID { get; set; }

    public SuperHero(Int32 id, String name, Int32 pid)
    {
        this.ID = id;
        this.Name = name;
        this.ParentID = pid;
    }

    public Int32 CompareTo(SuperHero right)
    {
        if (this.ID == right.ID)
            return 0;

        return this.ParentID.CompareTo(right.ID);
    }

    public override string ToString()
    {
        return this.Name;
    }
}

and to use it: 并使用它:

static void Main(string[] args)
{
    // create your list
    List<SuperHero> heroes = new List<SuperHero>();

    // populate it
    heroes.Add(new SuperHero(1, "Superman", 0));
    heroes.Add(new SuperHero(2, "Batman", 3));
    heroes.Add(new SuperHero(3, "Watchman", 1));
    heroes.Add(new SuperHero(4, "Wolverine", 2));

    foreach (SuperHero hero in heroes)
        Console.WriteLine(hero.ToString());
    Console.WriteLine();

    // sort it
    heroes.Sort();

    foreach (SuperHero hero in heroes)
        Console.WriteLine(hero.ToString());

    Console.ReadKey();
}

The .NET sort (QuickSort) will use your comparer to sort the list. .NET排序(QuickSort)将使用您的比较器对列表进行排序。

Easy way: 简单的方法:

using System.Linq;
...
var sorted = unsorted.OrderBy(x=>x.parent_id);

More complicated/reusable way: 更复杂/可重用的方式:

In .NET you can use existing sorting facilities (like Array.Sort, List.Sort, LINQ's OrderBy, etc) just by replacing one single method. 在.NET中,只需替换一种方法,就可以使用现有的排序工具(例如Array.Sort,List.Sort,LINQ的OrderBy等)。 You need to implement a comparer (either by creating an object that implements IComparer, implementing IComparable on the objects being compared, or using a Comparison delegate.) 您需要实现一个比较器(通过创建实现IComparer的对象,对要比较的对象实现IComparable或使用“比较”委托)。

All the comparer's job is is to determine whether a given object is greater than or less than another object. 比较器的全部工作是确定给定对象是否大于或小于另一个对象。 As long as you do that and follow some basic rules (ie. if X is greater than Y, then Y must be less than X) then the sorting will be quick and painless. 只要您这样做并遵循一些基本规则(即,如果X大于Y,则Y必须小于X),那么排序将变得轻松快捷。

如果在对象中实现IComparable,则可以在Array或ArrayList集合上使用.Sort方法。

I guess you want the NULL parentId to be the first, followed by its child. 我想您希望NULL parentId是第一个,然后是它的孩子。
If so, you can call OrderBy on the list using linq. 如果是这样,您可以使用linq在列表上调用OrderBy。

OrderBy(x => Convert.ToInt32(x.ParentId == null ? "0" : x.ParentId));

I am assuming ParentId is a string (it can not be null if it is an int). 我假设ParentId是一个字符串(如果是int,则不能为null)。
And assuming that the list won't have Id = 0. 并假设列表中没有Id = 0。

EDIT: This will print the items in the following order 编辑:这将按以下顺序打印项目
Superman 超人
Watchman 守望者
Wolverine 金刚狼
Batman 蝙蝠侠

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM