【问题标题】:Working with Lists, Anonymous Types and Suchlike使用列表、匿名类型等
【发布时间】:2011-06-08 09:52:21
【问题描述】:

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

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

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

在高层次上,这将涉及字符串上的 Split 以分隔名称组件,然后 ToTitleCase() 两个部分,然后将新值存储在 List 中的另一个对象中,然后我可以使用 @ 进行排序987654325@

我突然想到,我正在尝试学习的所有这些花哨的新语法可能包括用几行简洁代码执行此过程的方法。任何人都可以确认或否认这一点吗?

谢谢。

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

我需要从用户名中创建单独的名字和姓氏字段以进行排序,并从用户名中创建绑定到下拉列表的字段。这看起来很疯狂,但效果很好,我现在坚持使用它。非常感谢您的 cmets。

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;
除了ToTitleCaseing 之外,

似乎做了诀窍我需要的一切。但是,当然可能有更快/更简洁/更优雅的方法,所以我将把它打开一两天看看会发生什么;-)

【问题讨论】:

  • 您可以发布您的解决方案作为答案吗?谢谢。
  • 我不认为你可以在 Linq to SQL 的情况下执行 ToTitleCase。因为没有相应的 SQL 构造来执行 ToTitleCase 所做的操作,因此 linq2sql 无法将表达式解析为 SQL。但是你可以在从 SQL 获取数据后在集合对象中做 ToTitleCase
  • @BillTheLizard - 完成。 @Ankur - 我的解决方案(在 OP 下方的 'EDIT 3' 下)工作正常。 ToTitleCase() 是我编写的一个快速 n 脏扩展方法,它使用 TextInfo 对象的方法。我在这里不处理 LINQ to SQL - 原始集合是从数据库中检索的。

标签: c# list sorting anonymous-types


【解决方案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 - 对我的老眼睛来说,可读性大大降低,但简洁明了。我是否正确假设这与我的解决方案在功能上相同?
  • @OneSHOT - 请查看我对问题的编辑 - 不确定是否可以做我想做的事......
  • @OneSHOT - 伟大的思想家认为 [几乎] 相似 - 请参阅下面的“最终解决方案” - 我认为它做同样的事情,但有更多的 f4cked-about-with 匿名类。非常感谢您的 cmets。
  • @OneSHOT - 非常感谢 - 这是一段令人生畏的代码!以我目前的理解水平,我认为我的尝试更具可读性/可维护性。
  • @5arx 啊,我没有注意到前面的问题,在这种情况下,我能想到的最少代码量是上面直接跟在“编辑:编辑 3" 的更改,但如果我以后有时间我会看看我是否能想出其他任何东西!
【解决方案2】:

这是我想出的最终解决方案 - 排序、ToTitleCases 和格式。如果我自己这么说,那就太漂亮了。花了我整个上午 :-(

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

【讨论】:

    猜你喜欢
    • 2018-10-16
    • 2019-03-04
    • 2012-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多