C# 如何对字符[]列表进行排序?

C# 如何对字符[]列表进行排序?,c#,.net,arrays,list,sorting,C#,.net,Arrays,List,Sorting,我有以下清单: List<char[]> list1 = new List<char[]>(); List list1=新列表(); 我需要对它们上面的所有char[]元素进行排序。如果我使用list1.Sort()它说它不能比较元素,你知道如何对它排序吗 我真的需要列表是char[]而不是string如果您希望char[]具有作为string排序的确切行为,您可以这样做: list1 = list1.OrderBy(x => new string(x)).To

我有以下清单:

List<char[]> list1 = new List<char[]>();
List list1=新列表();
我需要对它们上面的所有
char[]
元素进行排序。如果我使用
list1.Sort()
它说它不能比较元素,你知道如何对它排序吗


我真的需要列表是
char[]
而不是
string

如果您希望
char[]
具有作为
string
排序的确切行为,您可以这样做:

list1 = list1.OrderBy(x => new string(x)).ToList();
您还可以根据需要使用:

这不需要创建新列表

另一种方法是为
Char[]
实现自己的
IComparer
。这应该是可行的,尽管它确实是可以改进的,而且没有经过测试。相关部分是
比较法
方法:

public class CharArrayComparer : IComparer<Char[]>, IEqualityComparer<Char[]>
{
    public CharArrayComparer() : this(false) {  }
    public CharArrayComparer(bool ignoreCase)
    {
        IgnoreCase = ignoreCase;
    }
    public bool IgnoreCase { get; set; }

    public int Compare(char[] x, char[] y)
    {
        if (x == null && y != null) return -1;
        if (y == null && x != null) return 1;
        if (y == null && x == null) return 0;
        int minLength = Math.Min(x.Length, y.Length);
        for(int i = 0; i < minLength; i++)
        {
            char c1 = IgnoreCase ? char.ToUpperInvariant(x[i]) : x[i];
            char c2 = IgnoreCase ? char.ToUpperInvariant(y[i]) : y[i];
            if (c1 < c2) return -1;
            else if (c2 < c1) return 1;
        }

        return x.Length - y.Length;
    }

    public bool Equals(char[] x, char[] y)
    {
        if (x == null || y == null) return false;
        if (x.Length != y.Length) return false;
        for (int i = 0; i < x.Length; i++)
        {
            char c1 = IgnoreCase ? char.ToUpperInvariant(x[i]) : x[i];
            char c2 = IgnoreCase ? char.ToUpperInvariant(y[i]) : y[i];
            if (c1 != c2) return false;
        }

        return true;
    }

    public int GetHashCode(char[] chars)
    {
        if(chars == null) return 0;
        int hash = 17;
        unchecked
        {
            foreach (char c in chars)
            {
                if(IgnoreCase)
                    hash = hash * 31 + char.ToUpperInvariant(c).GetHashCode();
                else
                    hash = hash * 31 + c.GetHashCode();
            }
        }
        return hash;
    }
}

使用List.Sort()时,列表元素应为可比的(实现可比接口)
因此,如果您有特殊的比较,我更愿意为元素创建一个新类,通过实现Comparable接口并将CompareTo方法重写为您自己的比较机制

您需要单独对每个数组进行排序还是将所有数组排序在一起?因此,您希望将char数组作为字符串进行排序,因此['A','B','C']将在['A','C','B']之前?如果您能给出一个简短但完整的示例,说明您试图实现的目标,这将非常有帮助。可能不太快,但请列出1.OrderBy(x=>新字符串(x))应该这样做。你想如何排序?你能举个例子吗?@Rawling:我想这是合乎逻辑的做法。这不会对
list1
的值所引用的现有列表进行排序。它返回一个新序列,但根本不会修改现有列表。仍然不会修改现有列表:p(顺便说一句,这不是我的DV,我很乐意等待OP澄清)@Rawling:另外,关于“如果”:OP说他不想使用
string
作为数据类型。看起来他确实打算做
string
排序,但那只是我的2美分。看起来你选择的很明智:)不过它确实需要构建更多的字符串……但我不认为有现成的排序可以避免这种情况。@Rawling:我已经尝试实现了一个,但尚未测试。无论如何可能会有帮助。@TimSchmelter-感谢这个解决方案-为我节省了大量开发工作。我唯一的评论是,您可能想更改最终返回的字符串将Compare函数的值设置为“return x.Length-y.Length”;因为如果x&y共享到最小长度的相同字符,则较长的字符数组相对大于较短的字符数组。
public class CharArrayComparer : IComparer<Char[]>, IEqualityComparer<Char[]>
{
    public CharArrayComparer() : this(false) {  }
    public CharArrayComparer(bool ignoreCase)
    {
        IgnoreCase = ignoreCase;
    }
    public bool IgnoreCase { get; set; }

    public int Compare(char[] x, char[] y)
    {
        if (x == null && y != null) return -1;
        if (y == null && x != null) return 1;
        if (y == null && x == null) return 0;
        int minLength = Math.Min(x.Length, y.Length);
        for(int i = 0; i < minLength; i++)
        {
            char c1 = IgnoreCase ? char.ToUpperInvariant(x[i]) : x[i];
            char c2 = IgnoreCase ? char.ToUpperInvariant(y[i]) : y[i];
            if (c1 < c2) return -1;
            else if (c2 < c1) return 1;
        }

        return x.Length - y.Length;
    }

    public bool Equals(char[] x, char[] y)
    {
        if (x == null || y == null) return false;
        if (x.Length != y.Length) return false;
        for (int i = 0; i < x.Length; i++)
        {
            char c1 = IgnoreCase ? char.ToUpperInvariant(x[i]) : x[i];
            char c2 = IgnoreCase ? char.ToUpperInvariant(y[i]) : y[i];
            if (c1 != c2) return false;
        }

        return true;
    }

    public int GetHashCode(char[] chars)
    {
        if(chars == null) return 0;
        int hash = 17;
        unchecked
        {
            foreach (char c in chars)
            {
                if(IgnoreCase)
                    hash = hash * 31 + char.ToUpperInvariant(c).GetHashCode();
                else
                    hash = hash * 31 + c.GetHashCode();
            }
        }
        return hash;
    }
}
list1.Sort(new CharArrayComparer());