У меня есть класс person, который содержит id and name. И у меня есть список person. Я хочу sort the list by Id. Затем отсортируйте элементы с same ID by name и преобразуйте name to uppercase letters, и, наконец, повторяющиеся элементы будут удалены.
List<person> list = new List<person>();
list.Add(new person(112, "Bname"));
list.Add(new person(111, "Cname"));
list.Add(new person(112, "Aname"));
list.Add(new person(111, "Aname"));
list.Add(new person(114, "Aname"));
Желаемый результат:
111,ANAME
111,CNAME
112,ANAME
112,BNAME
114,ANAME
Мой код:
for (int i = 0; i < list.Count - 1; i++)
{
if (list[i + 1].Id < list[i + 1].Id && string.Compare(list[i + 1].Name, list[i + 1].Name) > 0)
{
person temp = list[i];
list[i] = list[i + 1];
list[i + 1] = temp;
i = -1; //sort from lowest out of order index
}
}
for (int i = 0; i < list.Count - 1; i++)
{
list[i].Name= list[i].Name.ToUpper();
if (list[i] == list[i + 1])
list.Remove(list[i + 1]);
}
Но результат неверный. Кто-нибудь может мне помочь?
Когда вы говорите «повторяющиеся элементы удаляются», будут ли элементы с одинаковыми идентификаторами, но разными именами считаться дубликатами? Или они дублируются только в том случае, если совпадают имя и идентификатор? (Я спрашиваю, потому что немного странно иметь ситуацию, когда несколько элементов могут иметь один и тот же идентификатор...)
Вы можете сделать все это легко с linq.
1- с помощью OrderBy(x => x.Id упорядочить список с идентификатором
2- используйте ThenBy(x=>x.Name) для сортировки по имени с одинаковым идентификатором
3- используя .Select(x=>new {Id=x.Id,Name= x.Name.ToUpper()}) для преобразования имени в верхний регистр
4- используя .Distinct() для удаления дубликатов
var result=list.OrderBy(x => x.Id).ThenBy(x=>x.Name)
.Select(x=>new {Id=x.Id,Name= x.Name.ToUpper()}).Distinct().ToList();
Я думаю, что в вашем ответе есть две проблемы: во-первых, вы выбираете, что вы меняете ссылку на объекты, а второй метод не оптимизирован для памяти .Distinct(), поскольку его документы называют равными, и он не может сравнивать два определенных разработчиком объекта по умолчанию, если только метод ovveride Equals
@sinafayazi Правильно, но если OP использует тип record, это автоматически обеспечит правильную реализацию Equals().
Первое переопределение Equals вашего класса person для сравнения двух объектов, таких как
public override bool Equals(object? obj)
{
return Id == (obj as person)?.Id && Name == (obj as person)?.Name;
}
Тогда вы можете использовать пространство имен linq
list = list.OrderBy(x => x.Id).ThenBy(x => x.Name).ToList();
list.ForEach(x => x.Name = x.Name.ToUpper());
list = list.Distinct().ToList();
list.ForEach(x => x.Name = x.Name.ToUpper());
Если вы переопределяете Equals, переопределяйте и GetHashcode.