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());