Перейти к содержимому

Как отсортировать лист по возрастанию c

  • автор:

Сортировка данных (C#)

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

На следующем рисунке показаны результаты операции сортировки в алфавитном порядке в последовательности символов:

Рисунок с операциями сортировки в алфавитном порядке.

Далее перечислены методы стандартных операторов запроса, которые выполняют сортировку данных.

Методы

Имя метода Описание Синтаксис выражения запроса C# Дополнительные сведения
OrderBy Сортировка значений в возрастающем порядке. orderby Enumerable.OrderBy

Примеры синтаксиса выражений запросов

Примеры основной сортировки

Основная сортировка по возрастанию

В следующем примере показано использование предложения orderby в запросе LINQ для сортировки строк в массиве по длине строки в порядке возрастания.

string[] words = ["the", "quick", "brown", "fox", "jumps"]; IEnumerable query = from word in words orderby word.Length select word; foreach (string str in query) Console.WriteLine(str); /* This code produces the following output: the fox quick brown jumps */ 
Основная сортировка по убыванию

В следующем примере показано использование предложения orderby descending в запросе LINQ для сортировки строк по их первой букве в порядке убывания.

string[] words = ["the", "quick", "brown", "fox", "jumps"]; IEnumerable query = from word in words orderby word.Substring(0, 1) descending select word; foreach (string str in query) Console.WriteLine(str); /* This code produces the following output: the quick jumps fox brown */ 

Примеры дополнительной сортировки

Дополнительная сортировка по возрастанию

В следующем примере показано использование предложения orderby в запросе LINQ для выполнения основной и дополнительной сортировки строк в массиве. Строки сортируются основным образом по длине и дополнительно — по первой букве строки; в обоих случаях в возрастающем порядке.

string[] words = ["the", "quick", "brown", "fox", "jumps"]; IEnumerable query = from word in words orderby word.Length, word.Substring(0, 1) select word; foreach (string str in query) Console.WriteLine(str); /* This code produces the following output: fox the brown jumps quick */ 
Дополнительная сортировка по убыванию

В следующем примере показано использование предложения orderby descending в запросе LINQ для выполнения основной сортировки по возрастанию и дополнительной сортировки по убыванию. Строки сортируются основным образом по длине и дополнительно — по первой букве строки.

string[] words = ["the", "quick", "brown", "fox", "jumps"]; IEnumerable query = from word in words orderby word.Length, word.Substring(0, 1) descending select word; foreach (string str in query) Console.WriteLine(str); /* This code produces the following output: the fox quick jumps brown */ 

См. также

  • System.Linq
  • Общие сведения о стандартных операторах запроса (C#)
  • предложение orderby
  • Упорядочение результатов предложения соединения
  • Практическое руководство. Сортировка или фильтрация текстовых данных по любому слову или полю (LINQ) (C#)

Совместная работа с нами на GitHub

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

Как отсортировать данные в List, чтобы строки с числами были по возрастанию?

Есть список, в который мы грузим имена файлов из текущей директории Пример файлов — 0.jpg , 1.jpg , 2.jpg и т.д. Как отсортировать список по возрастанию? Одно дело если бы там были цифры. А когда в list содержит строковые данные-они сортируются некорректно. 0.jpg,1.jpg и 10.jpg

List list = new List(); DirectoryInfo d = new DirectoryInfo(Directory.GetCurrentDirectory()); FileInfo[] Files = d.GetFiles("*.jpg"); //Getting Text files string str = ""; foreach(FileInfo file in Files )

Отслеживать
32.1k 19 19 золотых знаков 79 79 серебряных знаков 106 106 бронзовых знаков
задан 18 ноя 2015 в 17:46
Radzhab 654654 Radzhab 654654
379 1 1 золотой знак 3 3 серебряных знака 19 19 бронзовых знаков
Поясните, чем вас не устроила сортировка строк из коробки?
18 ноя 2015 в 17:49
18 ноя 2015 в 17:53

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Можно попробовать так:

list.Sort((x, y) => < int ix, iy; return int.TryParse(x, out ix) && int.TryParse(y, out iy) ? ix.CompareTo(iy) : string.Compare(x, y); >); 
public class NaturalSortComparer : IComparer, IDisposable < private bool isAscending; public NaturalSortComparer(bool inAscendingOrder = true) < this.isAscending = inAscendingOrder; >#region IComparer Members public int Compare(string x, string y) < throw new NotImplementedException(); >#endregion #region IComparer Members int IComparer.Compare(string x, string y) < if (x == y) return 0; string[] x1, y1; if (!table.TryGetValue(x, out x1)) < x1 = Regex.Split(x.Replace(" ", ""), "([0-9]+)"); table.Add(x, x1); >if (!table.TryGetValue(y, out y1)) < y1 = Regex.Split(y.Replace(" ", ""), "([0-9]+)"); table.Add(y, y1); >int returnVal; for (int i = 0; i < x1.Length && i < y1.Length; i++) < if (x1[i] != y1[i]) < returnVal = PartCompare(x1[i], y1[i]); return isAscending ? returnVal : -returnVal; >> if (y1.Length > x1.Length) < returnVal = 1; >else if (x1.Length > y1.Length) < returnVal = -1; >else < returnVal = 0; >return isAscending ? returnVal : -returnVal; > private static int PartCompare(string left, string right) < int x, y; if (!int.TryParse(left, out x)) return left.CompareTo(right); if (!int.TryParse(right, out y)) return left.CompareTo(right); return x.CompareTo(y); >#endregion private Dictionary table = new Dictionary(); public void Dispose() < table.Clear(); table = null; >> 
list.OrderBy(item => item, new NaturalSortComparer()).ToList(); 

Отслеживать
ответ дан 18 ноя 2015 в 17:59
Мстислав Павлов Мстислав Павлов
6,767 2 2 золотых знака 18 18 серебряных знаков 40 40 бронзовых знаков

Насколько я понял из вашего описания, вас интересует «естественная» сортировка (natural sort), которая правильно отсортирует числа в строковом виде, например, «1, 2, 10, 20» вместо «1, 10, 2, 20». В Windows для этого есть встроенная функция StrCmpLogical . Чтобы воспользоваться ей для сортировки строк и файлов, вам понадобится реализовать интерфейс IComparer .

[SuppressUnmanagedCodeSecurity] internal static class NativeMethods < [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] public static extern int StrCmpLogicalW(string psz1, string psz2); >public sealed class NaturalStringComparer : IComparer  < public int Compare(string a, string b) < return NativeMethods.StrCmpLogicalW(a, b); >> public sealed class NaturalFileInfoNameComparer : IComparer  < public int Compare(FileInfo a, FileInfo b) < return NativeMethods.StrCmpLogicalW(a.Name, b.Name); >> 

Ну а дальше эти компареры можно передавать в любую сортирующую функцию. Так как у вас массив, то можно так:

Array.Sort(Files, new NaturalFileInfoNameComparer()); 

Как отсортировать лист по возрастанию c

Для сортировки набора данных в LINQ можно применять оператор orderby :

int[] numbers = < 3, 12, 4, 10>; var orderedNumbers = from i in numbers orderby i select i; foreach (int i in orderedNumbers) Console.WriteLine(i);

Оператор orderby принимает критерий сортировки. В данном случае в качестве критерия выступает само число. Результат работы программы:

3 4 10 12

Если числа сортируются стандартным образом, как принято в математике, то строки сортируются исходя из алфавитного порядка:

string[] people = < "Tom", "Bob", "Sam" >; var orderedPeople = from p in people orderby p select p; foreach (var p in orderedPeople) Console.WriteLine(p); // Bob Sam Tom

Вместо оператора orderby можно применять метод расширения OrderBy() :

OrderBy (Func keySelector) OrderBy (Func keySelector, IComparer? comparer);

Первая версия метода получает делегат, который через параметр получает элемент коллекции и который возвращает значение, применяемое для сортировки. Вторая версия позволяет также задать принцип сортировки через реализацию интерфейса IComparer.

Перепишем предыдущие два примера с помощью метода OrderBy:

int[] numbers = < 3, 12, 4, 10 >; var orderedNumbers = numbers.OrderBy(n=>n); foreach (int i in orderedNumbers) Console.WriteLine(i); string[] people = < "Tom", "Bob", "Sam" >; var orderedPeople = people.OrderBy(p=>p); foreach (var p in orderedPeople) Console.WriteLine(p);

Сортировка сложных объектов

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

var people = new List < new Person("Tom", 37), new Person("Sam", 28), new Person("Tom", 22), new Person("Bob", 41), >; // с помощью оператора orderby var sortedPeople1 = from p in people orderby p.Name select p; foreach (var p in sortedPeople1) Console.WriteLine($" - "); // с помощью метода OrderBy var sortedPeople2 = people.OrderBy(p => p.Name); foreach (var p in sortedPeople2) Console.WriteLine($" - "); record class Person(string Name, int Age);

Сортировка по возрастанию и убыванию

По умолчанию оператор orderby и метод OrderBy производят сортировку по возрастанию. С помощью ключевых слов ascending (сортировка по возрастанию) и descending (сортировка по убыванию) для оператора orderby можно явным образом указать направление сортировки. Например, отсортируем массив чисел по убыванию:

int[] numbers = < 3, 12, 4, 10 >; var orderedNumbers = from i in numbers orderby i descending select i; foreach (int i in orderedNumbers) Console.WriteLine(i); // 12 10 4 3

Для сортировки по убыванию можно применять метод OrderByDescending() , который работает аналогично OrderBy за исключением направления сортировки:

int[] numbers = < 3, 12, 4, 10 >; var orderedNumbers = numbers.OrderByDescending(n => n); foreach (int i in orderedNumbers) Console.WriteLine(i); // 12 10 4 3

Множественные критерии сортировки

В наборах сложных объектов иногда встает ситуация, когда надо отсортировать не по одному, а сразу по нескольким полям. Для этого в запросе LINQ все критерии указываются в порядке приоритета через запятую:

var people = new List < new Person("Tom", 37), new Person("Sam", 28), new Person("Tom", 22), new Person("Bob", 41), >; // с помощью оператора orderby var sortedPeople1 = from p in people orderby p.Name, p.Age select p; foreach (var p in sortedPeople1) Console.WriteLine($" - ");
Bob - 41 Sam - 28 Tom - 22 Tom - 37

Для разных критериев сортировки можно установить направление:

// с помощью оператора orderby var sortedPeople1 = from p in people orderby p.Name, p.Age descending // сортировка по возрасту по убыванию select p;

С помощью методов расширения то же самое можно сделать через метод ThenBy() (для сортировки по возрастанию) и ThenByDescending() (для сортировки по убыванию):

var sortedPeople2 = people.OrderBy(p => p.Name).ThenByDescending(p=>p.Age);

Результат будет аналогичен предыдущему.

Переопределение критерия сортировки

С помощью реализации IComparer мы можем переопределить критерии сортировки, если они нас не устраивают. Например, строки по умолчанию сортируются в алфавитном порядке. Но что, если мы хотим сортировать строки исходя из их длины? Решим данную задачу:

string[] people = new[]; var sortedPeople = people.OrderBy(p => p, new CustomStringComparer()); foreach (var p in sortedPeople) Console.WriteLine(p); // сравнение по длине строки class CustomStringComparer : IComparer  < public int Compare(string? x, string? y) < int xLength = x?.Length ?? 0; // если x равно null, то длина 0 int yLength = y?.Length ?? 0; return xLength - yLength; >>

Интерфейс IComparer типизируется типов сортируемых данных (в данном случае типом String). Для реализации этого интерфейса необходимо определить метод Compare. Он возвращает число: если первый параметр больше второго, то число больше 0, если меньше — то число меньше 0. Если оба параметра равны, то возвращается 0.

В данном случае, если параметр равен null, будем считать что длина строки равна 0. И с помощью разницы длин строк из обоих параметров определяем, какой из них больше.

Tom Sam Kate Mike Alice

12.6.5. Операция list::sort()

По умолчанию sort() упорядочивает элементы списка по возрастанию с помощью оператора «меньше», определенного в классе элементов контейнера. Вместо этого можно явно передать в качестве аргумента оператор сравнения. Так,

упорядочивает list1 по возрастанию, а

упорядочивает list1 по убыванию, используя оператор «больше».

Читайте также

Создание списка:

Создание списка: <fo:list-block> Для начала воспользуйтесь элементом <fo:list-block>, чтобы создать список XSL-FO; этот объект содержит элементы <fo:list-item>, содержащие данные списка.С элементом <fo:list-block> можно применять следующие свойства:• общие свойства доступа: source-document,

Список (List)

Список (List) list — вид последовательности, которая поддерживает двунаправленные итераторы и позволяет операции вставки и стирания с постоянным временем в любом месте последовательности, с управлением памятью, обрабатываемым автоматически. В отличие от векторов и

Сортировка (Sort)

Сортировка (Sort) template ‹class RandomAccessIterator›void sort(RandomAccessIterator first, RandomAccessIterator last);template ‹class RandomAccessIterator, class Compare›void sort(RandomAccessIterator first, RandomAccessIterator last, Compare соmр);sort сортирует элементы в диапазоне [first, last). Делается приблизительно NIogN (где N равняется last-first) сравнений в среднем. Если

12.6.2. Операция list::remove()

12.6.2. Операция list::remove() void list::remove( const elemType &value );Операция remove() удаляет все элементы с заданным значением:ilist1.remove( 1

12.6.3. Операция list::remove_if()

12.6.3. Операция list::remove_if() template class Predicate void list::remove_if( Predicate pred );Операция remove_if() удаляет все элементы, для которых выполняется указанное условие, т.е. предикат pred возвращает true. Например:class Even >;ilist1.remove_if( Even() );удаляет все четные числа из списка,

12.6.4. Операция list::reverse()

12.6.4. Операция list::reverse() void list::reverse();Операция reverse() изменяет порядок следования элементов списка на

12.6.6. Операция list::splice()

12.6.6. Операция list::splice() void list::splice( iterator pos, list rhs );void list::splice( iterator pos, list rhs, iterator ix );void list::splice( iterator pos, list rhs,iterator first, iterator last );Операция splice() имеет три формы: перемещение одного элемента, всех элементов или диапазона из одного списка в другой. В каждом случае передается итератор,

12.6.7. Операция list::unique()

12.6.7. Операция list::unique() void list::unique();template class BinaryPredicatevoid list::unique( BinaryPredicate pred );Операция unique() удаляет соседние дубликаты. По умолчанию при сравнении используется оператор равенства, определенный для типа элементов контейнера. Например, если даны значения , то после

Элемент xsl:sort

Элемент xsl:sort Синтаксис этого элемента определяется в XSLT как:<xsl:sort select = «выражение» lang = «язык» data-type = «text» | «number» | «имя» order = «ascending» | «descending» case-order = «upper-first» | «lower-first» />В случае если xsl:for-each и xsl:apply-templates содержат элементы xsl:sort, обработка множества узлов должна производиться

11.1. Сортировка файлов с помощью команды sort

11.1. Сортировка файлов с помощью команды sort Команда sort позволяет выполнять сортировку входного потока по различным полям (ключам сортировки). Это довольно мощная команда, которая весьма полезна при обработке журнальных файлов или реорганизации текстовых столбцов в

11.1.1. Опции команды sort

11.1.1. Опции команды sort Команда sort имеет следующий формат:sort [опции] [входные_файлы]Команда выполняет конкатенацию указанных входных файлов, сортирует полученный текст и записывает результат в стандартный выходной поток. Если файлы не указаны, ожидается ввод данных с

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *