排序时使用另一个列表执行的交换来排列一个 c# 列表
本文关键字:列表 排列 一个 交换 另一个 执行 排序 | 更新日期: 2023-09-27 18:36:09
我有两个 c# 列表,当我根据某个露营者对一个列表进行排序时,我需要在第一个列表执行交换后对另一个列表进行排序,而不会使用太多额外的空间。
//function
private int ColumnSortCriteria(List<double> p1, List<double> p2)
{
if (p1[0] > p2[0])
return 1;
if ((float) p1[0] == (float) p2[0] && p2[1] > p2[1])
return 1;
if (p1[0] == p2[0] && p1[1] == p2[1])
return 0;
return -1;
}
// main goes from here ......
List<List<double>> WallEndPoints1 = new List<List<double>>();
List<List<double>> WallEndPoints2 = new List<List<double>>();
WallEndPoints1.sort(ColumnSortCriteria)
有点评论(但很长)。
从您的排序标准方法中,我推断您的p1
和p2
(因此您的"内部"List<>
)总是有 2 Count
。那为什么不对他们使用Tuple<double, double>
呢?然后你有:
List<Tuple<double, double>> WallEndPoints1 = new List<Tuple<double, double>>();
List<Tuple<double, double>> WallEndPoints2 = new List<Tuple<double, double>>();
您可以像这样向列表添加点:
WallEndPoints1.Add(Tuple.Create(7.3, -0.5));
// etc.
您的ColumnSortCriteria
变得简单:
//function
static int ColumnSortCriteria(Tuple<double, double> p1, Tuple<double, double> p2)
{
// lexicographic
return System.Collections.StructuralComparisons.StructuralComparer.Compare(p1, p2);
}
然后,如果本着德米特里回答的精神,将两个列表组合(压缩)在一起,你会得到:
List<Tuple<Tuple<double, double>, Tuple<double, double>>> combinedEndPoints
= WallEndPoints1.Zip(WallEndPoints2, Tuple.Create).ToList();
(var
关键字的情况?
在这种情况下,您可以像这样排序:
combinedEndPoints.Sort((a, b) => ColumnSortCriteria(a.Item1, b.Item1));
它按第一对(.Item1
)对对进行排序,其中第一对按字典顺序进行比较。如果第一对与成对相同,则顺序未定义。
对我来说,这是对你的问题最可能的解释。
也许你想要的是"简单":
combinedEndPoints.Sort(System.Collections.StructuralComparisons.StructuralComparer.Compare);
它按一种"嵌套"或"深度"词典排序对列表进行排序。
当然,如果您不想遵循我的建议并更改WallEndPoints1
和WallEndPoints2
的类型以包括Tuple<,>
,解决方案看起来仍然相同:
List<Tuple<List<double>, List<double>>> combinedEndPoints
= WallEndPoints1.Zip(WallEndPoints2, Tuple.Create).ToList();
combinedEndPoints.Sort((a, b) => ColumnSortCriteria(a.Item1, b.Item1));
现在ColumnSortCriteria
是问题中的原始方法(原始签名)。
无论哪种情况,正如 Dmitry 在他的回答中所说,从"组合"列表中选择一个组件以仅查看"1"或仅查看"2",即:
var wallEndPoints1Sorted = combinedEndPoints.Select(x => x.Item1);
var wallEndPoints2Sorted = combinedEndPoints.Select(x => x.Item2);
我建议将两个列表合并为一个:
// I've used Tuple<T1, T2>, but probably you have a better class for point
List<Tuple<Double, Double>> WallEndPoints = new List<Tuple<Double, Double>>() {
new Tuple<Double, Double>(3.0, 5.0),
...
new Tuple<Double, Double>(15.0, 20.0),
};
然后按第一个组件排序:
WallEndPoints.Sort((left, right) => left.Item1.CompareTo(right.Item1));
或词典(按第一分,按第二分列):
WallEndPoints.Sort((left, right) => {
int result = left.Item1.CompareTo(right.Item1);
return result != 0 ? result : left.Item2.CompareTo(right.Item2);
});
每当你想要第一个/第二个组件时,你可以使用 Linq:
var xs = WallEndPoints.Select(item => item.Item1);
var ys = WallEndPoints.Select(item => item.Item2);