1

私が持っていると言う

List<int> ages  = new List<int>() { 8, 5, 3, 9, 2, 1, 7 };
List<int> marks = new List<int>() { 12, 17, 08, 15, 19, 02, 11 };

marks次のように並べ替えることができますages

while (true)
{
  bool swapped = false;

  for (int i = 0; i < ages.Count - 1; i++)
    if (ages[i] > ages[i + 1])
    {
      int tmp = ages[i];
      ages[i] = ages[i + 1];
      ages[i + 1] = tmp;

      tmp = marks[i];
      marks[i] = marks[i + 1];
      marks[i + 1] = tmp;

      swapped = true;
    }

  if (!swapped)
    break;
}

これを任意の 2 つのリストを受け入れる関数に入れたいと思います。最初のパラメーターは、参照リスト、数値または比較可能なリストになります。2 番目のパラメーターは、データを含むリストになります。

例えば:

public static void Sort<T>(List<T> RefList, List<T> DataList)
{
  // sorting logic here...
}

いくつかの問題があります:

まず第一に、Tはほぼ確実に と で同じ型ではRefListありませんDataList。RefList は、日付、整数、または double の可能性があります。一方、DataList は自由に何でも構いません。任意のジェネリック型を 2 つ受け取ることができる必要があります。

第二に、次の行で>演算子を使用できないようです。T

if (ages[i] > ages[i + 1])

おそらく私のアプローチ全体が間違っています。

ところで、2 つのリストを複合データ型の 1 つのリストに結合する必要があることを示唆する同様の質問への回答を読んだことがあります。これは、私のアプリケーションではまったく実用的ではありません。私がやりたいことは、あるリストを別のリストの要素に基づいてソートする静的関数を作成することだけです。

4

4 に答える 4

8

1 つのリストを希望どおりに並べ替えるには、最初のリストの項目から 2 番目のリストの重み/キーへの参照を保持する必要があります。メタデータを任意の値に簡単に関連付けることができないため、既存のメソッドはそれを行いません(つまり、最初のリストがリストのint場合、2番目のリストのキーにマップするものはありません)。唯一の合理的なオプションは、同時に 2 つのリストを並べ替え、インデックスで関連付けを行うことです。ここでも、役立つ既存のクラスはありません。

拒否したソリューションを使用する方がはるかに簡単な場合があります。つまり、最初のリストを再作成するよりも、単純に Zip と OrderBy を使用します。

ages = ages
  .Zip(marks, (a,m)=> new {age = a; mark = m;})
  .OrderBy(v => v.mark)
  .Select(v=>v.age)
  .ToList();

注(phoogの礼儀):Arrayでこのタイプのソートを行う必要がある場合は、正確にこの操作を可能にするArray.Sortがあります(詳細についてはphoogの回答を参照してください)。

于 2013-01-09T03:27:26.310 に答える
8

でこれを行うためのフレームワーク メソッドはありList<T>ませんが、データを 2 つの配列に入れることを気にしない場合は、Array.Sort()2 つの配列を引数として受け取るオーバーロードの 1 つを使用できます。最初の配列はキーで、2 番目の配列は値なので、コードは次のようになります (リストから配列を取得するステップは別として)。

Array.Sort(ages, marks);

値を配列に取得してからリストに戻す詳細は、特に、同じリストを適切にソートする必要があるかどうか、またはデータを目的の順序で新しいリストに戻してもよいかどうかによって異なります。

于 2013-01-09T03:37:09.843 に答える
4

使用する:

public static void Sort<TR, TD>(IList<TR> refList, IList<TD> dataList)
        where TR : System.IComparable<TR>
        where TD : System.IComparable<TD>
{
 ...
}

そして、次を使用します。

refList[i].CompareTo(refList[i+1])

オペレーターの代わりに。

.Net 番号は既に IComparable を実装しており、別の IComparable を指定できるオーバーロードを使用できます。

于 2013-01-09T03:29:59.643 に答える
2

「自分のマークを年齢で並べ替えるとこうなる」ということをちゃんと理解していれば、

多くの混乱を避けるために、以下を提案したいと思います。

struct Student{
    int age;
    int marks;
};

List<Student> students = {{8,12}, ...};

年齢に応じて並べ替えることができるようになり、それに応じてマークが自動的に並べ替えられます。

それができない場合は、以下のようにコードを修正する必要があります。

まず第一に、T は RefList と DataList でほぼ確実に同じ型ではありません。

次に、2 つのパラメーター T1、T2 が必要です。ただ T は、型が同じであることを意味します。

public static void Sort<RefType, DataType>(List<RefType> RefList, List<DataType> DataList)
{

また、Mechanical Snail によって提案され、一度に 2 つのリストをループするで説明されているように、2 つのリストを一緒に圧縮することもできます。

于 2013-01-09T03:20:14.183 に答える