Работа со списками, анонимными типами и т.п. - PullRequest
0 голосов
/ 08 июня 2011

Исходя из предыдущего вопроса , теперь у меня есть коллекция анонимного типа

[User: Имя пользователя (как forename.surname, Идентификатор пользователя ].

Эту коллекцию «пользователей» в конечном итоге необходимо привязать к выпадающему списку. Это нормально, но мне нужно отсортировать их по фамилии и имени. но это усложняется тем, что формат имени пользователя - имя_фамилия.

На высоком уровне это будет включать Split в строке для разделения компонентов имени, затем ToTitleCase() обе части, затем сохранение новых значений в другом объекте в списке, который я затем смогу отсортировать с помощью 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);

Мне нужно создать отдельные поля имени и фамилии из имени пользователя для сортировки и имени пользователя для привязки к выпадающему списку. Это кажется безумным, но это работает так хорошо, что я придерживаюсь этого пока. Буду признателен за ваши комментарии.

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 ing. Но, конечно, может быть еще более быстрый / более краткий / более элегантный метод, поэтому я оставлю это открытым на день или два, чтобы посмотреть, что произойдет; -)

Ответы [ 2 ]

1 голос
/ 08 июня 2011

Чуть меньший код может быть достигнут с использованием лямбда-выражений, а не синтаксиса выражений, поэтому

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

но это больше кода, который я не уверен, что вы хотите.

Последние изменения:

ваш код не требует группировки по операторам, так что вы можете уменьшить это, выполнив

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

Кроме этого, единственный способ уменьшить этот вызов - использовать определенный класс, как указано выше, это не значит, что это невозможно сделать! но я не вижу как!

НТН

OneShot

0 голосов
/ 08 июня 2011

Вот окончательное решение, которое я придумал - оно сортирует, ToTitleCase s и форматы.Скорее изящно, если я сам так скажу.Взял меня все утро, хотя: - (

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