Упорядочить по буквам алфавита AL и MZ, используя лямбду - PullRequest
0 голосов
/ 15 мая 2019

Добрый день,

В моем примере сценария я пытаюсь выбрать всех пользователей из моей базы данных и затем поместить в мое dto, где есть списки упорядочения по буквам алфавита, с учетом следующего: A-L, M-Z

Вот мой пример кода с общим OrderBy именем пользователя:

var users = await users.Users().ToListAsync();

return users.Select(u=>new CategorizedByLetterUserDto{
    ...
}).OrderBy(u=>u.Name);

Итак, мой образец CategorizedByLetterUserDto выглядит следующим образом.

public class CategorizedByLetterUserDto {
     public IEnumerable<AtoL> AtoL {get;set}    
     public IEnumerable<MtoZ> MtoZ {get;set;}
     ...
}

public class AtoL{
     public int Id {get;set;}
     public string Name {get;set;}
}

public class MtoZ{
     public int Id {get;set;}
     public string Name {get;set;}
}

so on and so forth...

Таким образом, результат будет (массив)

 {
     categorizedByLetterUserDto: {
         atoL: [
         {
           ...
         }
         ],
         mtoZ: [
         {
           ...
         }
         ]
     }
 }

Ответы [ 3 ]

2 голосов
/ 15 мая 2019

Используйте GroupBy, что-то вроде этого:

 var grouped = users.GroupBy(u => u.Name.CompareTo("M") < 0).OrderBy(g => g.Key).ToArray();
 return new CategorizedByLetterUserDto
 {
    AtoL = grouped[1].Select(x => new UserDto { Id = x.Id, Name = x.Name }),
    MtoZ = grouped[0].Select(x => new UserDto { Id = x.Id, Name = x.Name }),
 };

И не создавайте идентичные классы, используйте:

public class UserDto
{
    public int Id {get;set;}
    public string Name {get;set;}
}

Вместо этого вы можете использовать ToLookup, и в этом случае это будет эквивалентно, но подробности относительно того, когда это не так, см. https://stackoverflow.com/a/10215531/224370.

И если вы хотите разделить более чем на одну точку разделения, вы можете сделать что-то вроде:

string splits = "EMT";
var grouped = users.GroupBy(u => splits.Count(c => u.Name[0] > c))
                     .OrderBy(g => g.Key).ToArray(); ...

Примечание: пуристы предпочли бы отсортированный список разделенных символов и метод двоичного поиска, чтобы найти индекс, но для большинства практических небольших наборов разделенных символов это будет быстрее и меньше кода, и не важно, в каком порядке точки разделения указаны в.

0 голосов
/ 15 мая 2019

Я не думаю, что вам нужно вмешиваться, вы можете просто использовать существующие функции LINQ для создания поисков

List<User> list = ... .OrderBy(u=>u.Name); //from db 

ILookup<int, User> lookup = list.ToLookup(
  u => (u.Name[0] - 63)/14,
  u => new Dto { Id = u.Id, Name = u.Name }
);

Числа относятся к обработке char как int в таблице ascii, A, являющейся 65. Вычитая 63, A становится 2, L становится 13, Z становится 27. К тому же, деля на 14, мы уменьшаем это до 0 или 1 Теперь ваш поиск будет представлять собой список пользователей, проиндексированных по 0 или 1, где 0 соответствует AtoL. Если вы хотите, чтобы пользователи в указанном списке были отсортированы, вы можете вызвать OrderBy для них. Я сделал это с помощью математики, а не сравнения bool, чтобы вы могли изменить его на большее количество столбцов в будущем, просто изменив числа, но вы также можете использовать bool:

var lookup = list.ToLookup(
  u => u.Name[0]<'M',
  u => new Dto { Id = u.Id, Name = u.Name }
);

В этом поиске возвращается, индексированный по истине будет от А до L

Назначьте вашему категорированному Dto:

var x = new CatDto(){ 
  aToL=lookup[true],   
  mToZ=lookup[false] 
};

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

0 голосов
/ 15 мая 2019

Лучше использовать класс List <> вместо IEnumerable <> в своем классе CategorizedByLetterUserDto для доступа к методу .Add. Затем попробуйте код ff.

var users = await users.Users().ToListAsync();
char[] listOfAtoL = "ABCDEFGHIJKL".toCharArray();
CategorizedByLetterUserDto cat = new CategorizedByLetterUserDto();

foreach (User u in users.OrderBy(a => a.Name)) {
    listOfAtoL.Contains(char.ToUpper(u.Name.toCharArray()[0])) ? cat.AtoL.Add(new AtoL() {id = u.ID, Name = u.Name}) : cat.MtoZ.Add(new MtoZ() {id = u.ID, Name = u.Name});
}

return cat;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...