根据另一个列出一个列表

说我有

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

我可以按照以下ages对我的marks进行排序:

 while (true) { bool swapped = false; for (int i = 0; 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(List RefList, List DataList) { // sorting logic here... } 

有一些问题:

首先, T几乎肯定与RefListDataList类型RefList 。 RefList可能是日期,整数或双打; 而DataList可以完全免费。 我需要能够接收两个任意generics类型。

其次,我似乎无法在此行中使用带有T>运算符:

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

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

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

要按照您希望的方式对一个列表进行排序,您实际上需要以某种方式将第一个列表中的项目的引用保留到第二个列表中的权重/键。 没有现有方法可以做到这一点,因为您无法轻松地将元数据与任意值相关联(即,如果第一个列表是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的答案)。

使用List没有框架方法可以做到这一点,但如果你不介意将数据放入两个数组,你可以使用一个Array.Sort()重载,它将两个数组作为参数。 第一个数组是键,第二个是值,因此您的代码可能如下所示(不考虑从列表中获取数组的步骤):

 Array.Sort(ages, marks); 

将值转换为数组然后返回列表的具体细节取决于您是否需要以相应的列表进行适当排序,或者是否可以按所需顺序返回包含数据的新列表

使用:

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

然后使用:

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

而不是运营商。

.Net编号已经实现了IComparable,您可以使用允许您指定不同IComparable的重载。

如果我理解“我可以按照这样的年龄对我的分数进行分类:”

我想建议以下消除很多混乱。

 struct Student{ int age; int marks; }; List students = {{8,12}, ...}; 

现在您可以根据年龄进行排序,并自动对标记进行排序。

如果不可能,您需要修复如下代码。

首先,T几乎肯定与RefList和DataList中的类型不同。

那你需要2个参数T1,T2。 Just T暗示类型是相同的。

 public static void Sort(List RefList, List DataList) { 

您也可以按照Mechanical Snail的建议将两个列表压缩在一起,并在一次循环浏览2个列表中进行说明