排序时使用另一个列表执行的交换来排列一个c#列表

排序时使用另一个列表执行的交换来排列一个c#列表,c#,sorting,C#,Sorting,我有两个c#列表,当我根据某个camparator对一个列表进行排序时,我需要在第一个列表执行交换之后对另一个列表进行排序,而不会占用太多额外的空间 //function private int ColumnSortCriteria(List<double> p1, List<double> p2) { if (p1[0] > p2[0]) return 1; if ((float) p1[0] == (float) p2[0]

我有两个c#列表,当我根据某个camparator对一个列表进行排序时,我需要在第一个列表执行交换之后对另一个列表进行排序,而不会占用太多额外的空间

//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)
//函数
私有int列标准(列表p1、列表p2)
{
如果(p1[0]>p2[0])
返回1;
如果((浮点)p1[0]==(浮点)p2[0]&&p2[1]>p2[1])
返回1;
if(p1[0]==p2[0]&&p1[1]==p2[1])
返回0;
返回-1;
}
//从这里开始。。。。。。
List WallEndPoints1=新列表();
List WallEndPoints2=新列表();
WallEndPoints1.sort(ColumnSortCriteria)
我建议将两个列表合并为一个:

// 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),
};
或词汇(按第一个成分,按第二个成分):

无论何时需要第一/第二个组件,都可以使用Linq:

有点像评论(但很长)

根据排序标准方法,我推断您的
p1
p2
(因此您的“内部”
列表
)的
计数始终为两个。那么为什么不为它们使用
Tuple
?那么你有:

List<Tuple<double, double>> WallEndPoints1 = new List<Tuple<double, double>>();
List<Tuple<double, double>> WallEndPoints2 = new List<Tuple<double, double>>();
而您的
专栏SortCriteria
变得简单:

//function 
static int ColumnSortCriteria(Tuple<double, double> p1, Tuple<double, double> p2) 
{
  // lexicographic
  return System.Collections.StructuralComparisons.StructuralComparer.Compare(p1, p2);
}
它按第一对(
.Item1
)对成对进行排序,第一对按字典顺序进行比较。如果第一对与第二对相同,则顺序未定义

对我来说,这是对你的问题最可能的解释

也许你想要的是“简单”:

它通过一种“嵌套的”或“深层的”词典排序对成对的列表进行排序


当然,如果您不希望按照我的建议将
wallendomps1
wallendomps2
的类型更改为包含
元组
,那么解决方案看起来仍然是一样的:

List<Tuple<List<double>, List<double>>> combinedEndPoints
  = WallEndPoints1.Zip(WallEndPoints2, Tuple.Create).ToList();

combinedEndPoints.Sort((a, b) => ColumnSortCriteria(a.Item1, b.Item1));

是否可以将两个列表合并为一个?说
List
,然后按第一个组件排序?为什么强制转换为
float
?p1
p2
计数总是正好是两个?它们真的是2D点吗?@JeppeStigNielsen Stig Nielsen 1这只是决定函数是否交换两个列表的一个示例。主要的问题是如何在不直接合并和使用额外空间的情况下将交换顺序保持到另一个列表——只需找到任何现有的开源排序例程,并用应该交换的两个位置的委托回调替换任何“交换”操作。然后,您可以同时对任意多个列表进行排序。也许他希望按字典顺序进行排序,因此,当第一个组件相等时,使用第二个组件作为平局开关。@Jeppe Stig Nielsen:
Sort
函数中的lambda稍作修改即可按字典顺序进行排序。内部列表包含两点(point1.X在0上,point1.Y在1上,point2.X在2上,依此类推)和一堆其他信息。但我在排序条件中仅使用point1。因此不能使用tuple@Gitesh请参阅此答案的新扩展(位于水平标尺下方)。
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.
//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();
combinedEndPoints.Sort((a, b) => ColumnSortCriteria(a.Item1, b.Item1));
combinedEndPoints.Sort(System.Collections.StructuralComparisons.StructuralComparer.Compare);
List<Tuple<List<double>, List<double>>> combinedEndPoints
  = WallEndPoints1.Zip(WallEndPoints2, Tuple.Create).ToList();

combinedEndPoints.Sort((a, b) => ColumnSortCriteria(a.Item1, b.Item1));
var wallEndPoints1Sorted = combinedEndPoints.Select(x => x.Item1);
var wallEndPoints2Sorted = combinedEndPoints.Select(x => x.Item2);