【问题标题】:Lambda expression for custom sort of list自定义列表类型的 Lambda 表达式
【发布时间】:2015-09-15 04:18:50
【问题描述】:

我有一个 MyClass 列表,其中一个属性是 Position。最初,职位可能是这样的:

2,-3,1,3,4,5,-2,-1,

使用 Sort (NOT .OrderBy) 方法,我需要一个 lambda 表达式,它将导致上述数字从最低正数排序,然后从最低负数排序数字,所以输出是这样的:

1,2,3,4,5,-1,-2,-3

我是 lambda 表达式的新手,我已经做到了这一点:myList.Sort((x, y) => x.Position.CompareTo(y.Position)),但它并不能完全满足我的要求。

干杯!

【问题讨论】:

    标签: c# list sorting lambda


    【解决方案1】:

    当x.Position 和y.Position 均为正数或均为负数时,您可以按绝对值对它们进行排序。 否则,使用CompareTo函数的取反值

    myList.Sort((x,y) => x.Position > 0 && y.Position > 0 || x.Position < 0 && y.Position < 0 ? 
                          Math.Abs(x.Position).CompareTo(Math.Abs(y.Position)) :
                          -x.Position.CompareTo(y.Position));
    

    【讨论】:

    • -x.CompareTo 应该是 -x.Position.CompareTo。一旦我做出了改变,它就完美地工作了!谢谢!
    【解决方案2】:

    您需要将自己的自定义IComparable 实现到您的MyClass 并实现CompareTo。更多信息可以找到here。这是一个没有使用IComparable的直接示例。

    using System;
    using System.Linq;
    using System.Collections.Generic;
    public class Test
    {
        public static void Main()
        {
            var myList = new List<int>() { 2,-3,1,3,4,5,-2,-1,};
            myList.Sort(Compare);
            foreach(var item in myList){
                Console.WriteLine(item);
            }
        }
    
        static int Compare(int x, int y)
        {
         if (x > 0 && y < 0)
         {
            return -1;
         }
    
         if (x < 0 && y > 0)
         {
            return 1;
         }
    
         if (x < 0 && y < 0)
         {
            return y.CompareTo(x);
         }
         return x.CompareTo(y);
        }
    }
    

    对于对象 A、B 和 C,必须满足以下条件: A.CompareTo(A) 必须返回零。 如果 A.CompareTo(B) 返回零,则 B.CompareTo(A) 必须返回零。 如果 A.CompareTo(B) 返回零且 B.CompareTo(C) 返回零,则 A.CompareTo(C) 必须返回零。 如果 A.CompareTo(B) 返回一个非零值,则 B.CompareTo(A) 必须返回一个相反符号的值。 如果 A.CompareTo(B) 返回一个不等于 0 的值 x,并且 B.CompareTo(C) 返回一个与 x 符号相同的值 y,那么 A.CompareTo(C) 必须返回一个与 x 符号相同的值x 和 y。 来电者须知 使用 CompareTo 方法来确定类实例的顺序。

    【讨论】:

      【解决方案3】:
      static int Cmp(int x, int y)
      {
          if (x > 0 && y < 0)
          {
              return -1;
          }
      
          if (x < 0 && y > 0)
          {
              return 1;
          }
      
          if (x < 0 && y < 0)
          {
              return y.CompareTo(x);
          }
      
          return x.CompareTo(y);
      }
      //---
      List<int> list = new List<int> { 2, -3, 1, 3, 4, 5, -2, -1 };
      list.Sort(Cmp);
      

      【讨论】:

        【解决方案4】:
         class ListOperations
        {
            public static void Main(string[] args)
            {
                List<Book> books = new List<Book>
               {
                   new Book { Name="book1",ISBN= 554654,Category= "Mathematics",Price=12.45,Index=1},
                   new Book { Name="book2",ISBN= 454654, Category="English", Price=-6.45, Index=3},
                   new Book {Name="book3",ISBN= 754654, Category="English", Price=7.45, Index=4 },
                   new Book { Name = "book4", ISBN = 854654,Category= "History", Price=8.45,Index= 5 },
                   new Book { Name = "book5", ISBN = 154654, Category="Mathematics", Price=17.45, Index=2 },
                   new Book { Name = "book6", ISBN = 354654, Category="History", Price=-15.45, Index=6 },
                   new Book { Name = "book7", ISBN = 354653, Category="History", Price=0, Index=6 }
                };
                books.Sort((x, y) =>( x.Price > 0 && y.Price > 0 || x.Price < 0 && y.Price < 0 )? Math.Abs(x.Price).CompareTo(Math.Abs(y.Price)) : -x.Price.CompareTo(y.Price));
            }
        
            class Book
            {
                public string Name { get; set; }
                public int ISBN { get; set; }
                public string Category { get; set; }
                public double Price { get; set; }
                public double Index { get; set; }
                public int RowNum { get; set; }
            }
        }
        

        【讨论】:

          【解决方案5】:

          此代码适用于您的情况。

          var values = new[] {2,-3,1,3,4,5,-2,-1};
          var solution = values.GroupBy(i => i > 0)
              .SelectMany(g => g.Key? g.OrderBy(c=>c) : g.OrderByDescending(c=>c))
              .ToArray();
          

          工作sample附在这里。

          【讨论】:

          • 您的代码不起作用。它将产生输出 2 -3 1 3 4 5 -2
          • @lll 你能检查一下我附上的样本吗?
          • 我做到了。它不编译。
          • @lll 你是什么意思它不编译?这是工作。我认为在不验证代码和链接的情况下投反对票是不公平的。
          • 我确实验证了代码和链接。另外,它坏了,所以你一定已经修好了,我没有投反对票。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多