0

我目前正在学习 C# 中的 LINQ,并且想知道是否有更好的方法来使用Max()LINQ 语句中的函数返回对象。

这是我的用户类:

public class User
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public double MonthlyWage { get; set; }
    }

这是我的表人口类:

public class UsersTable
    {
        public IList<User> Populate()
        {
            IList<User> Users = new List<User>()
            {
                new User{ID = 1, Name = "Bob", MonthlyWage = 1200.00},
                new User{ID = 2, Name = "Lee", MonthlyWage = 2200.00},
                new User{ID = 3, Name = "Dan", MonthlyWage = 3200.00},
                new User{ID = 4, Name = "Liam", MonthlyWage = 4200.00},
                new User{ID = 5, Name = "Danny", MonthlyWage = 4213.00},
                new User{ID = 6, Name = "Jonathan", MonthlyWage = 1222.00},
                new User{ID = 7, Name = "Martin", MonthlyWage = 1233.00},
                new User{ID = 8, Name = "Dec", MonthlyWage = 9999.99}
            };
            return Users;
        }
    }

这是主要方法:

class Program
    {
        static void Main(string[] args)
        {
            UsersTable UserTable = new UsersTable();
            IList<User> Users = UserTable.Populate();

            double max = Users.Max(x => x.MonthlyWage);
            var maxMonthlyWage = Users
                .Where(m => m.MonthlyWage == max)
                .Select(x => x);

            foreach (var item in maxMonthlyWage)
            {
                Console.WriteLine("{0}: {1} {2} MAX", item.ID, item.Name, item.MonthlyWage);
            }

            Console.ReadLine();
    }

double max有没有一种方法可以在不预先创建每月工资最高的情况下返回用户?这是执行此类查询的最佳方式吗?

4

2 回答 2

4

一个班轮

  var item = Users.OrderByDescending(x => x.MonthlyWage).FirstOrDefault();

  if(item != null)
    Console.WriteLine("{0}: {1} {2} MAX", item.ID, item.Name, item.MonthlyWage);

  Console.ReadLine();

如果我们想要所有高收入者:

var wageGroups = from u in Users
                group u by u.MonthlyWage into ug
                orderby ug.Key descending
                select new { MonthlyWage = ug.Key, Users = ug.ToList() };

var topEarners = wageGroups.First().Users;

foreach (var item in topEarners)
{
    Console.WriteLine("{0}: {1} {2} MAX", item.ID, item.Name, item.MonthlyWage);
}

Console.ReadLine();
于 2013-09-12T14:19:57.133 回答
1

您可以将所有内容放在一起:

var maxMonthlyWage = Users
                    .OrderByDescending(x => x.MonthlyWage)
                    .TakeWhile(x => x.MonthlyWage == Users.Max(y => y.MonthlyWage))
                    .ToList();

注意:我刚刚回答了 OP 关于删除中间变量的问题(也删除了一些冗余位)。无论如何,我不想被误解:从效率的角度来看,所提出的方法并不比 OP 的方法好。

注意 2:正如 MarcinJuraszek 强调的那样,此查询执行两次分析。他提出了一个外部库来避免这种情况(moreLINQ)。其他选项可能依赖于First(由 Tommy Grovnes 提出),尽管这只会产生一个结果(不太可能是 OP 似乎正在寻找的)。

注意 3:正如 MarcinJuraszek 正确强调的那样,原始 O​​P 的代码仅迭代一次以计算最大值。我的答案的新版本(比最初的更好)仍然迭代不止一次,因此效率低于原始版本。尽管如此,OP 要求删除中间变量,这就是这个答案的原因。

于 2013-09-12T14:14:21.317 回答