自定义C#数组的排序顺序

自定义C#数组的排序顺序,c#,arrays,sorting,irc,C#,Arrays,Sorting,Irc,这已经困扰我一段时间了。我尝试过几种方法,但没有一种能正常工作 我正在编写和IRC客户端,并试图整理用户名列表(需要按照当前频道中用户的访问级别进行排序) 这很容易。问题是,每当用户加入或离开频道时,都需要将此列表添加到列表中,因此在用户离开时必须将其用户名从列表中删除,并在用户重新加入时将其重新添加到正确的位置 每个用户的访问级别由每个用户名开头的单个字符表示。这些字符是保留的,因此名称以其中一个符号开头不存在潜在问题。从最高到最低的符号(按照我需要排序的顺序)为: ~ & @ % + 没有任

这已经困扰我一段时间了。我尝试过几种方法,但没有一种能正常工作

我正在编写和IRC客户端,并试图整理用户名列表(需要按照当前频道中用户的访问级别进行排序)

这很容易。问题是,每当用户加入或离开频道时,都需要将此列表添加到列表中,因此在用户离开时必须将其用户名从列表中删除,并在用户重新加入时将其重新添加到正确的位置

每个用户的访问级别由每个用户名开头的单个字符表示。这些字符是保留的,因此名称以其中一个符号开头不存在潜在问题。从最高到最低的符号(按照我需要排序的顺序)为: ~ & @ % +

没有任何访问权限的用户在其用户名前没有符号。它们应该在列表的底部

例如:未排序的数组可能包含以下内容: ~user1~user84@user3&user8+user39 user002 user2838%user29

并且需要进行排序,以便元素按以下顺序排列: ~user1~user84&user8@user3%user29+user39 user002 user2838

用户按访问级别排序后,还需要按字母顺序排序

在这里提问是最后的办法,如果有人能帮我,我将非常感激。
提前谢谢。

只要数组包含对象,就在对象上实现IComparable,然后调用array.Sort()


如果集合是可更改的,我建议使用列表。

您可以使用
SortedList
,K(键)实现
IComparable
接口,然后定义排序标准。V可以是空的,也可以是相同的K对象。

您可以给
数组提供
i比较程序或
比较程序。然后,您只需要自己实现比较。如果这是一个相对复杂的比较(听起来像这样),我会在一个单独的类中实现
IComparer
,您可以轻松地进行单元测试。然后打电话:

Array.Sort(userNames, new UserNameComparer());
如果UserNameComparer没有状态,您可能需要定义一个方便的实例:

Array.Sort(userNames, UserNameComparer.Instance);
List
也有类似的排序选项——如果你想定期添加/删除项目,我个人会使用列表而不是数组

事实上,听起来你并不经常需要做一个完整的排序。删除用户不会更改排序顺序,插入只意味着在正确的点插入。换句话说,您需要:

  • 创建列表并对其排序以
  • 删除用户只是一个简单的操作
  • 添加用户需要找到将其插入的位置

您可以使用
Array.BinarySearch
List.BinarySearch
执行最后一步,这同样允许您指定自定义的
IComparer
。一旦您知道在哪里插入用户,就可以相对便宜地完成这项工作(与再次对整个集合进行排序相比)。

您应该看看界面(或者它的功能)。在实现
CompareTo
方法时,请检查两个用户名中是否有一个包含您的保留字符。如果两者都没有特殊的保留字符或具有相同的字符,请调用
String.CompareTo
方法,该方法将处理字母排序。否则,请使用自定义排序逻辑。

我尝试了排序,并提出了以下排序方法:

List<char> levelChars = new List<char>();
levelChars.AddRange("+%@&~".ToCharArray());
List<string> names = new List<string>();
names.AddRange(new[]{"~user1", "~user84",  "@user3", "&user8", "+user39", "user002", "user2838", "%user29"});
names.Sort((x,y) =>
               {
                   int xLevel = levelChars.IndexOf(x[0]);
                   int yLevel = levelChars.IndexOf(y[0]);

                   if (xLevel != yLevel)
                   {
                       // if xLevel is higher; x should come before y
                       return xLevel > yLevel ? -1 : 1;
                   }

                   // x and y have the same level; regular string comparison
                   // will do the job
                   return x.CompareTo(y);                       
               });
List levelChars=new List();
levelChars.AddRange(“+%@&~”.ToCharArray());
列表名称=新列表();
names.AddRange(新[]{“~user1”、“~user84”、“@user3”、“&user8”、“+user39”、“user002”、“user2838”、“user29”});
name.Sort((x,y)=>
{
int xLevel=levelChars.IndexOf(x[0]);
int-yLevel=levelChars.IndexOf(y[0]);
如果(xLevel!=yLevel)
{
//如果xLevel更高,则x应在y之前
返回xLevel>yLevel?-1:1;
}
//x和y具有相同的级别;常规字符串比较
//我会做好的
返回x.CompareTo(y);
});

这个比较代码也可以存在于
IComparer
实现的
Compare
方法中。

他可能希望按值排序,而不是按键排序。。。似乎是一种非常非常迂回的方法。在本例中,实际上不是-keys==值。如果您已经有了一个排序列表,那么每次添加元素时调用Sort()是非常低效的。无论如何,如果您想要一个更干净的解决方案,您可以使用PowerCollections的OrderedSet,例如()可能最好使用IComparable而不是非泛型IComparable,或者继承掉Compariable,它实现了这两个方面,如果OP使用列表,IComparable会更好,但我认为这对Array.Sort()不起作用这需要IComparable。如何存储用户名列表?如果它是一个数据库,那么在将数据放入列表之前,是否可以使用SQL按所需顺序检索数据?