使用列表,匿名类型和类似

时间:2011-06-08 09:52:22

标签: c# list sorting anonymous-types

earlier question开始,我现在有一个匿名类型的集合

[用户:     用户名(forename.surname,     用户身份 ]

这个'用户'集合最终需要绑定到下拉列表。这很好,但我需要做的是按姓氏和姓名对它们进行排序。但由于用户名格式为forename.surname,这很复杂。

在高级别,这将涉及字符串上的Split以分隔名称组件,然后ToTitleCase()两个部分,然后将新值存储在List中的另一个对象中,我可以然后使用List<T>.OrderBy(...).ThenBy(...)

排序

在我看来,我试图学习的所有这些花哨的新语法可能包括在几行简洁代码中执行此过程的方法。任何人都可以确认或否认这个吗?

感谢。

编辑3:

我想我已经破解了它:

var salesusers =    (
                      from s in lstReport 
                      group s by new { s.SalesUserId,s.Username} 
                      into g
                      select new
                          {
                             Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
                             Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
                             Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
                             UserId = g.Key.SalesUserId 
                           }
                     ).OrderBy(a=> a.Surname).ThenBy(a=> a.Forename);

我需要从用户名创建单独的forename和surname字段以进行排序,并使用用户名绑定到下拉列表。它看起来很疯狂,但它的工作原理很好我现在坚持使用它。非常感谢您的评论。

EDIT2: 所以我得到了这个。现在我想知道语法是否允许我将我之前问题的Group by操作与此步骤结合起来..

var sortedUsers = from u in salesusers
                  orderby u.UserName.Split('.')[1], u.UserName.Split('.')[0]
                  select new {UserName = u.UserName.Replace(".", " ").ToTitleCase(), UserId = u.UserId.Value};

任何人......?

编辑:我设法自己做一切大部分,以防万一有人需要,但在订购时转换名称组件ToTitleCase操作证明是困难的。

这:

var sortedUsers = from u in salesusers
                  orderby u.UserName.Split('.')[1], u.UserName.Split('.')[0]
                  select u;
除了ToTitleCase之外,

似乎做了技巧我需要的一切。但当然可能会有一个更快/更优雅/更优雅的方法,所以我会保持开放一两天,看看会发生什么; - )

2 个答案:

答案 0 :(得分:1)

使用lambdas而不是表达式语法可以实现更少的代码

var sorted = salesusers.OrderBy(u => u.UserName.Split('.')[1]).ThenBy(u => u.UserName.Split('.')[0]).ToList();

虽然它的可读性较差,但是一旦习惯了语法,我发现它比表达式语法更容易阅读。

编辑:编辑3的更改

转换为Lambdas的代码如下

var salesusers = (l.GroupBy(s => new { SalesUserId = s.SalesUserId, Username = s.Username }).Select(g =>new {
                                Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),
                                Surname = g.Key.Username.Split('.')[1].ToTitleCase(),
                                Forename = g.Key.Username.Split('.')[0].ToTitleCase(),
                                UserId = g.Key.SalesUserId
                    })).OrderBy(a => a.Surname).ThenBy(a => a.Forename);

唯一的问题是,表达越大,阅读越难!

另一种可以读取清晰度的方法是定义细节对象而不是使用动态对象。

internal class UserDetails
    {
        public UserDetails(User u)
        {
            this.Forename = u.Username.Split('.')[0].ToTitleCase();
            this.Surname = u.Username.Split('.')[1].ToTitleCase();
            this.UserId = u.SalesUserId;
            this.Username = u.Username;
        }

        public string Username { get; set; }
        public string Surname { get; set; }
        public string Forename { get; set; }

        public int UserId { get; set; }

    }

然后你可以做

var salesusers = (l.GroupBy(s => new { SalesUserId = s.SalesUserId, Username = s.Username })
    .OrderBy(u => u.Username.Split('.')[1].ToTitleCase())
    .ThenBy(u => u.Username.Split('.')[0].ToTitleCase())
    .Select(g => new UserDetails(g)));

但这是更多我不确定你想要的代码。

最新编辑:

您的代码不需要group by语句,因此您可以通过执行

来减少该代码
 var salesusers = (
                    from s in l
                        select new
                        {
                            Username = s.Username.Split('.')[1].ToTitleCase() + " " + s.Username.Split('.')[0].ToTitleCase(),
                            Surname = s.Username.Split('.')[1].ToTitleCase(),
                            Forename = s.Username.Split('.')[0].ToTitleCase(),
                            UserId = s.SalesUserId
                        }
                 ).OrderBy(a => a.Surname).ThenBy(a => a.Forename);

或者使用Lambdas成为

var salesusers = l.Select(g =>new {
                            Username = g.Username.Split('.')[1].ToTitleCase() + " " + g.Username.Split('.')[0].ToTitleCase(),
                            Surname = g.Username.Split('.')[1].ToTitleCase(),
                            Forename = g.Username.Split('.')[0].ToTitleCase(),
                            UserId = g.SalesUserId
                }).OrderBy(a => a.Surname).ThenBy(a => a.Forename);

除此之外,我可以看到进一步减少该调用的唯一方法是使用上面定义的类,这并不是说它无法完成!但我看不出来怎么样!

HTH

单次

答案 1 :(得分:0)

这是我提出的最终解决方案 - 它排序,ToTitleCase和格式。如果我自己这么说,那就相当漂亮了。我整个早上都告诉我: - (

var salesusers =    (
                        from s in lstReport 
                        group s by new { s.SalesUserId,s.Username} 
                        into g
                        select new
                            {
                                Username = g.Key.Username.Split('.')[1].ToTitleCase() + " " + g.Key.Username.Split('.')[0].ToTitleCase(),  
                                Surname = g.Key.Username.Split('.')[1].ToTitleCase(),  
                                Forename = g.Key.Username.Split('.')[0].ToTitleCase(),  
                                UserId = g.Key.SalesUserId 
                             }  
                     ).OrderBy(a=> a.Surname).ThenBy(a=> a.Forename);