1

これはしばらくの間私を悩ませてきました。いくつかのアプローチを試しましたが、適切に機能するものはありませんでした。

IRC クライアントを書いていて、ユーザー名のリストを整理しようとしています (これは、現在のチャネルでのユーザーのアクセス レベルで並べ替える必要があります)。

これは簡単です。問題は、このリストは、ユーザーがチャンネルに参加または退出するたびに追加する必要があるため、退出時にユーザー名をリストから削除し、再参加するときに正しい位置に再度追加する必要があることです。

各ユーザーのアクセス レベルは、各ユーザー名の先頭にある 1 文字で示されます。これらの文字は予約されているため、名前が記号の 1 つで始まるという潜在的な問題はありません。最高から最低までの記号 (並べ替える必要がある順序で) は次のとおりです。 ~ & @ % +

いかなる種類のアクセス権もないユーザーには、ユーザー名の前に記号がありません。それらはリストの一番下にあるはずです。

例: ソートされていない配列には次のものが含まれる可能性があります: ~user1 ~user84 @user3 &user8 +user39 user002 user2838 %user29

また、要素が次の順序になるように並べ替える必要があります: ~user1 ~user84 &user8 @user3 %user29 +user39 user002 user2838

ユーザーをアクセス レベルで並べ替えた後、アルファベット順に並べ替える必要もあります。

ここで質問するのは最後の手段です。誰かが私を助けてくれれば、とても助かります。前もって感謝します。

4

5 に答える 5

1

SortedList<K,V>K(キー)実装IComparableインターフェースで使用して、ソートの基準を定義することができます。Vは、単にnullまたは同じKオブジェクトにすることができます。

于 2009-06-24T09:52:04.083 に答える
1

IComparer<T>にまたはComparison<T>を与えることができますArray.Sort。次に、自分で比較を実装する必要があります。比較的複雑な比較の場合(このように聞こえます)IComparer<T>、別のクラスに実装します。これを簡単に単体テストできます。次に、電話します。

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

UserNameComparerに状態がない場合は、便利なインスタンスを定義することをお勧めします。

Array.Sort(userNames, UserNameComparer.Instance);

List<T>並べ替えにも同様のオプションがあります。アイテムを定期的に追加/削除する場合は、配列ではなくリストを個人的に使用します。

実際、実際に完全な並べ替えを行う必要はあまりないようです。ユーザーを削除しても並べ替え順序は変更されません。挿入とは、適切な場所に挿入することだけを意味します。言い換えれば、あなたは必要です:

  • リストを作成し、最初に並べ替えます
  • ユーザーの削除は簡単な操作です
  • ユーザーを追加するには、ユーザーを挿入する場所を見つける必要があります

Array.BinarySearchまたはを使用して最後の手順を実行できます。List.BinarySearchこれにより、カスタムを指定できますIComparer<T>。ユーザーを挿入する場所がわかれば、比較的安価に行うことができます(コレクション全体を再度並べ替える場合と比較して)。

于 2009-06-24T09:54:36.920 に答える
1

配列にオブジェクトが含まれている限り、オブジェクトにIComparableを実装してから、Array.Sort()を呼び出します。

コレクションが変更可能である場合は、リスト<>を使用することをお勧めします。

于 2009-06-24T09:50:24.820 に答える
0

IComparerインターフェイス(または汎用バージョン)を確認する必要があります。メソッドを実装するときCompareToは、2つのユーザー名のいずれかに予約文字の1つが含まれているかどうかを確認してください。どちらにも特別な予約文字がない場合、または両方に同じ文字がある場合は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 に答える