通过一个排序变量对各种对象的数据结构进行排序的最佳方法?

时间:2017-09-05 07:36:58

标签: c# algorithm sorting

给定包含一些其他对象的列表/对象数组,我希望使用其中一个参数进行排序。例如,如果我有一个多维的int数组,我想按它们的中点排序。

我这样做的方法是创建一个包含1.中点的匿名对象,以及2.每个条目的2个int的列表。然后登记这些对象并使用反射来访问和按中点参数排序。

这个问题有更标准的方法吗?它有点笨拙,因为我必须创建一个虚拟对象并清除匿名列表对象才能执行此操作。

class Program
{
    static void Main(string[] args)
    {
        int[,] input = new int[,] { { 5, 6 }, { 0, 1 }, { 2, 20 } };

        var itemList = new []{ 
          new { sortVar = 0.1f, item = new List<int>() } }.ToList();

        itemList.Clear();

        for(int i=0; i<input.GetLength(0); i++)
        {
            List <int> temp = new List<int> (new int[] { input[i,0], input[i, 1] });

            var item = new { 
              sortVar = float.Parse((input[i,0]+input[i,1]).ToString())/2,
              item = temp };

            itemList.Add(item);
        }

        var itemList2 = itemList.OrderBy(x => x.sortVar);
    }
}

2 个答案:

答案 0 :(得分:1)

您的方法的简短linq版本将直接在OrderBy子句中使用Average方法(如果您倾向于使用二维列表):

List<List<int>> input_List = new List<List<int>> 
{
    new List<int>{ 5, 6 }, 
    new List<int>{ 0, 1 }, 
    new List<int>{ 2, 20 } 
};

var output = input_List.OrderBy(x=>x.Average()).ToList();   

修改

如果您需要按中位数订购,可以使用以下表达式:

var output = input_List.OrderBy(x=>x.OrderBy(y=>y).ElementAt(x.Count / 2)).ToList();    

答案 1 :(得分:1)

我建议将 2D 数组更改为锯齿一个(数组数组):

   int[][] input = new int[][] { 
     new int[]{ 5,  6 }, 
     new int[]{ 0,  1 }, 
     new int[]{ 2, 20 } }; 

并提取标准(MidPoint)作为方法

   private static double MidPoint(IEnumerable<int> value) {
      int[] sorted = value.OrderBy(item => item).ToArray(); 

      // / 2.0: we don't want integer division: (1 + 4) / 2 == 2 when (1 + 4) / 2.0 == 2.5
      return sorted.Length % 2 == 0
        ? (sorted[sorted.Length / 2 - 1] + sorted[sorted.Length / 2]) / 2.0
        : sorted[sorted.Length / 2];
    } 

如果你想对进行排序使用Array类:

 // input will be sorted 
 Array.Sort(input, (a, b) => MidPoint(a).CompareTo(MidPoint(b)));

如果要创建 new 排序数组:

 // we'll have to arrays: initial (unsorted) input, and sorted sortedInput
 var sortedInput = input
   .OrderBy(line => MidPoint(line))
   .ToArray();