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

现在我想把它放到一个接受任何两个列表的函数中。第一个参数将是参考列表,数字或可比较的列表。第二个参数将是包含数据的列表。

例如:

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

有几个问题:

首先,几乎可以肯定和T中的类型不一样。RefList 可能是日期、整数或双精度数;而 DataList 可以自由地成为任何东西。我需要能够接收两种任意的泛型类型。RefListDataList

其次,我似乎无法在这一行中使用>运算符:T

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

也许我的整个方法都是错误的。

顺便说一句,我已经阅读了对类似问题的回复,这些问题表明这两个列表应该组合成一个复合数据类型的列表。这对我的应用程序来说根本不实用。我要做的就是编写一个静态函数,它以某种方式根据另一个列表的元素对一个列表进行排序。

4

4 回答 4

8

要按照您想要的方式对一个列表进行排序,您实际上需要以某种方式将第一个列表中的项目的引用保留到第二个列表中的权重/键。没有现有的方法可以做到这一点,因为您无法轻松地将元数据与任意值相关联(即,如果第一个列表是int您的情况的列表,则没有任何内容可以映射到第二个列表中的键)。您唯一合理的选择是同时对 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>,但如果您不介意将数据放入两个数组中,您可以使用Array.Sort()将两个数组作为参数的重载之一。第一个数组是键,第二个是值,因此您的代码可能如下所示(撇开从列表中获取数组的步骤):

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 的建议将两个列表压缩在一起,并在Looping through 2 Lists at once中解释

于 2013-01-09T03:20:14.183 回答