排序列表<>基于另一个的
本文关键字:另一个 列表 排序 | 更新日期: 2023-09-27 17:51:00
假设我有
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
中几乎肯定不是同一类型。RefList可以是日期、整数或双精度;而DataList可以自由地做任何事情。我需要能够接收两个任意泛型。
其次,我似乎不能将>
操作符与这一行的T
一起使用:
if (ages[i] > ages[i + 1])
也许我的整个方法都错了。
顺便说一下,我读过对类似问题的回答,建议将这两个列表组合成复合数据类型的单个列表。这对我的应用程序来说根本不实用。我所要做的就是编写一个静态函数,以某种方式根据一个列表的元素对另一个列表进行排序。要按您想要的方式排序一个列表,您实际上需要以某种方式保持从第一个列表中的项到第二个列表中的它们的权重/键的引用。没有现有的方法这样做,因为你不能轻易地将元数据与任意值相关联(即,如果第一个列表是int
的列表,因为在你的情况下,没有什么可以映射到第二个列表中的键)。你唯一合理的选择是同时对2个列表进行排序,并通过索引进行关联——同样没有现有的类来帮助。
使用你拒绝的解决方案可能更容易。例如,简单地压缩和排序,然后重新创建第一个列表:
ages = ages
.Zip(marks, (a,m)=> new {age = a; mark = m;})
.OrderBy(v => v.mark)
.Select(v=>v.age)
.ToList();
注意(由photo提供):如果您需要使用Array进行这种类型的排序,则有Array。
对于List<T>
没有框架方法可以做到这一点,但是如果您不介意将数据放入两个数组中,您可以使用一个Array.Sort()
重载,它将两个数组作为参数。第一个数组是键,第二个数组是值,因此您的代码可能看起来像这样(不考虑从列表中获取数组的步骤):
Array.Sort(ages, marks);
将值放入数组然后再返回到列表的细节取决于,除其他事项外,是否需要以相同的列表进行适当排序,或者是否可以返回一个新列表,其中包含所需的数据顺序
使用说明:
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 number已经实现了IComparable,您可以使用重载来指定不同的IComparable。
如果我正确理解"I can sort my marks by ages like this ",
为了避免混淆,我想提出以下建议。
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建议的,并在一次遍历两个列表