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

时间:2016-02-24 11:22:17

标签: c# sorting

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

//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)

2 个答案:

答案 0 :(得分:1)

我建议两个列表合并为一个:

// 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));

或lexicograhicaly(第1组成部分,第2组结合):

WallEndPoints.Sort((left, right) => {
  int result = left.Item1.CompareTo(right.Item1);

  return result != 0 ? result : left.Item2.CompareTo(right.Item2);  
});

无论何时需要第1 /第2个组件,您都可以使用 Linq

var xs = WallEndPoints.Select(item => item.Item1);
var ys = WallEndPoints.Select(item => item.Item2);

答案 1 :(得分:1)

有点评论(但很长)。

根据您的排序标准方法,我推断您的p1p2(因此您的“内部”List<>)总是有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);
}

然后,如果按照德米特里的回答,将两个列表组合在一起(zip),你会得到:

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

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

当然,如果您不希望遵循我的建议并将WallEndPoints1WallEndPoints2的类型更改为包含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);