1

这一直困扰着我一段时间。我尝试了几种方法,但都没有正常工作。

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

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

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

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

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

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

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

在这里问是最后的手段,如果有人可以帮助我,我将非常感激。先感谢您。

4

5 回答 5

1

只要数组包含一个对象,然后在该对象上实现 IComparable,然后调用 Array.Sort()。

如果集合是可变的,我建议使用 List<>。

于 2009-06-24T09:50:24.820 回答
1

您可以使用SortedList<K,V>K(键)实现IComparable接口,然后定义您的排序标准。V 可以简​​单地为 null 或相同的 K 对象。

于 2009-06-24T09:52:04.083 回答
1

你可以给 aIComparer<T>或 a Comparison<T>to Array.Sort。然后你只需要自己实现比较。如果这是一个相对复杂的比较(听起来像这样),我会IComparer<T>在一个单独的类中实现,您可以轻松地对其进行单元测试。然后调用:

Array.Sort(userNames, new UserNameComparer());

如果 UserNameComparer 没有状态,您可能希望定义一个方便的实例:

Array.Sort(userNames, UserNameComparer.Instance);

List<T>有类似的排序选项 - 如果您要定期添加/删除项目,我个人会使用列表而不是数组。

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

  • 创建列表并对其进行排序以开始
  • 删除用户只是一个简单的操作
  • 添加用户需要找出插入它们的位置

您可以使用Array.BinarySearchor来完成最后一步List.BinarySearch,这再次允许您指定自定义IComparer<T>. 一旦你知道在哪里插入用户,你就可以相对便宜地做到这一点(与再次对整个集合进行排序相比)。

于 2009-06-24T09:54:36.920 回答
0

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

于 2009-06-24T10:05:56.677 回答
0

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

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

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

于 2009-06-24T10:08:12.493 回答