List是否自动排序

本文关键字:排序 是否 List | 更新日期: 2023-09-27 17:50:05

我想知道列表自动排序还是什么?

我有

List<MyClass> myClass = new List<MyClass>()
myClass.Add(anotherClass);
myClass.Add(anotherClass2);
myClass.Add(anotherClass3);
myClass.Add(anotherClass4);

所以它们都是MyClass对象。里面有这样的东西

public class MyClass
{
   public string type {get; set;}
   public string title {get; set;}
}

List<MyClass> first = myClass .where(x => x.type == "first").toList();
List<MyClass> second = myClass .where(x => x.type == "second").toList();
first.Sort((x, y) => string.Compare(x.title, y.title));
second.Sort((x, y) => string.Compare(x.Title, y.Title));
myClass.Clear();
myClass.AddRange(first);
myClass.AddRange(second);

所以我的实际代码看起来像这样,除了"MyClass"更复杂,我把它们放在一个foreach循环中。

当我执行first.Sort()和second.Sort()时,我所有的对象都是基于Title的正确顺序。当我在第一个对象中清除并添加"first"对象,然后在第二个对象中添加"second"对象时,它会破坏我的排序。

我需要将类型为"first"的对象排在类型为"second"的对象之前。

比如我有

A - first
B - second
C - first
D - second

应该是

A
C
B
D

I am getting

A - First
B - second
C - First
D - second

List是否自动排序

不,List<T>总是按照您添加的顺序存储元素,除非您显式地在特定位置插入元素。

您可以要求进行排序,并提供一个自定义比较来排序——就像您所做的那样。

看起来你在为你想要的做正确的事情。如果我把我坐在火车车厢里的所有男人按年龄排序,然后据此创建一个列表,然后对女人做同样的事情,最后使用:

List<Person> allPeople = new List<Person>();
allPeople.AddRange(menSortedByAge);
allPeople.AddRange(womenSortedByAge);

我不会让everyone按年龄排序——我会得到所有的男性(按年龄排序),然后是所有的女性(按年龄排序)。这正是你应该看到的。

如果这不是你看到的,但它是你想要的,你需要给我们一个简短但完整的程序来演示问题。告诉我们你的期望和你实际得到的。

如果你只想按多个条件排序,最简单的方法就是使用LINQ:

var ordered = people.OrderBy(p => p.Gender)
                    .ThenBy(p => p.Age)
                    .ToList();

编辑:代码的演示(修复了错别字,为了简单起见使用了匿名类型):

using System;
using System.Collections.Generic;
using System.Linq;
class Test
{
    static void Main()
    {
        var myClass = new[]
        {
            new { Type="first", Title="A" },
            new { Type="second", Title="D" },
            new { Type="first", Title="C" },
            new { Type="second", Title="B" },
        }.ToList();
        var first = myClass.Where(x => x.Type == "first")
                           .ToList();
        var second = myClass.Where(x => x.Type == "second")
                            .ToList();
        first.Sort((x, y) => string.Compare(x.Title, y.Title));
        second.Sort((x, y) => string.Compare(x.Title, y.Title));
        myClass.Clear();
        myClass.AddRange(first);
        myClass.AddRange(second);
        foreach (var x in myClass)
        {
            Console.WriteLine(x);
        }
    }
}
输出:

{ Type = first, Title = A }
{ Type = first, Title = C }
{ Type = second, Title = B }
{ Type = second, Title = D }

您希望您的对象按类型排序,然后按标题?如果是这样,LINQ来拯救:

var sortedObjects = myClass.OrderBy(x => x.type).ThenBy(x => x.title);

当我执行first.Sort()和second.Sort()时,我所有的对象都是基于Title的正确顺序。当我在第一个对象中清除并添加"first"对象,然后在第二个对象中添加"second"对象时,它会破坏我的排序。

你为什么要清除它?这听起来很像下面的语句:

当我删除我的文件,我不能再打开它们。它们似乎从磁盘上消失了。

你可以这样排序:

// this is what you call to sort.
myClass.Sort(MyClass.NameComparison);
// This would sit in your class which you referenced as "MyClass"
public static NameComparison<MyClass> NameComparison
{
    get
    {
        return delegate(MyClass c1, MyClass c2)
        {
            return c1.Name.CompareTo(c2.Name);
        };
    }
}

这可以很容易地被

代替
      myClass.OrderBy((m) => m.type).ThenBy((m) => m.title);

这消除了需要第二个列表和清除等。

更面向对象的方法如何?只要实现iccomparable ,那么当你调用myList.Sort();时,列表就会神奇地知道如何对自己排序。

public class MyClass : IComparable<MyClass>
{
    public string Type {get; set;}
    public string Title {get; set;}
    public int CompareTo(MyClass other) 
    {
        if (other == null) 
        {
           throw new ArgumentNullException("other");
        }
        else if(this.Type == other.Type)
        {
            return this.Title.CompareTo(other.Title);
        }
        else if(this.Type == "first")
        {
            return 1;
        }
        else
        {
            return -1;
        }
        // ...Or whatever you feel your sort needs to take into account.
    }
}

它还可以让你讨厌的排序逻辑隐藏起来,让你看不到你真正想用列表做什么;