Узнайте, как управлять коллекциями данных с помощью List в C#
Это вводное руководство содержит общие сведения о языке C# и классе List .
Предварительные требования
Для работы с руководством вам потребуется компьютер, настроенный для разработки в локальной среде. Инструкции по установке и общие сведения о разработке приложений в .NET см. в статье Настройка локальной среды .
Если вы предпочитаете выполнять код без настройки локальной среды, ознакомьтесь с интерактивной версией этого руководства в браузере.
Пример простого списка
Создайте каталог с именем list-tutorial. Откройте этот каталог и выполните команду dotnet new console .
В шаблонах C# для .NET 6 используются операторы верхнего уровня. Приложение может не соответствовать коду, приведенному в этой статье, если вы уже выполнили обновление до .NET 6. Дополнительные сведения см. в статье Новые шаблоны C# для создания инструкций верхнего уровня.
Пакет SDK для .NET 6 также добавляет набор неявных global using директив для проектов, использующих следующие пакеты SDK:
- Microsoft.NET.Sdk
- Microsoft.NET.Sdk.Web
- Microsoft.NET.Sdk.Worker
Эти неявные директивы global using включают наиболее распространенные пространства имен для соответствующего типа проектов.
Откройте Program.cs в любом редакторе и замените существующий код следующим:
List names = ["", "Ana", "Felipe"]; foreach (var name in names) < Console.WriteLine($"Hello !"); >
Замените собственным именем. Сохраните Program.cs. Введите в окне консоли команду dotnet run для тестирования.
Вы создали список строк, добавили три имени в этот список и вывели имена прописными буквами. Для циклического прохода по списку вы примените концепции, которые изучили в предыдущих руководствах.
В коде для отображения имен используется функция интерполяции строк. Если перед string добавить символ $ , код C# можно внедрять в объявление строки. Фактическая строка заменяет код C# генерируемым значением. В этом примере она заменяет именами, буквы каждого из которых преобразованы в прописные, так как вызван метод ToUpper.
Изменение содержимого списка
Console.WriteLine(); names.Add("Maria"); names.Add("Bill"); names.Remove("Ana"); foreach (var name in names) < Console.WriteLine($"Hello !"); >
В конец списка добавлены еще два имени. При этом одно имя удалено. Сохраните файл и введите dotnet run для тестирования.
Console.WriteLine($"My name is "); Console.WriteLine($"I've added and to the list");
Доступ к индексу за пределами списка получить невозможно. Помните, что индексы начинаются с 0, поэтому максимальный допустимый индекс меньше, чем число элементов в списке. Вы можете проверить, как долго в списке используется свойство Count. Добавьте следующий код в конец программы:
Console.WriteLine($"The list has people in it");
Сохраните файл и еще раз введите dotnet run , чтобы просмотреть результаты.
Поиск по спискам и их сортировка
В наших примерах используются сравнительно небольшие списки. Но приложения часто создают списки с гораздо большим количеством элементов, иногда они исчисляются в тысячах. Чтобы найти элементы в таких больших коллекциях, необходимо выполнить поиск различных элементов по списку. Метод IndexOf выполняет поиск элемента и возвращает его индекс. Если элемент отсутствует в списке, IndexOf возвращает -1 . Добавьте этот код в конец программы:
var index = names.IndexOf("Felipe"); if (index == -1) < Console.WriteLine($"When an item is not found, IndexOf returns "); > else < Console.WriteLine($"The name is at index "); > index = names.IndexOf("Not Found"); if (index == -1) < Console.WriteLine($"When an item is not found, IndexOf returns "); > else < Console.WriteLine($"The name is at index "); >
Кроме того, можно сортировать элементы в списке. Метод Sort сортирует все элементы списка в обычном порядке (строки — в алфавитном). Добавьте этот код в конец программы:
names.Sort(); foreach (var name in names) < Console.WriteLine($"Hello !"); >
Сохраните файл и введите dotnet run , чтобы протестировать последнюю версию.
Прежде чем перейти к следующему разделу, переместим текущий код в отдельный метод. Это упростит начало работы с новым примером. Поместите весь написанный код в новый метод с именем WorkWithStrings() . Вызовите этот метод в начале кода программы. В результате ваш код должен выглядеть примерно следующим образом:
WorkWithStrings(); void WorkWithStrings() < Listnames = ["", "Ana", "Felipe"]; foreach (var name in names) < Console.WriteLine($"Hello !"); > Console.WriteLine(); names.Add("Maria"); names.Add("Bill"); names.Remove("Ana"); foreach (var name in names) < Console.WriteLine($"Hello !"); > Console.WriteLine($"My name is "); Console.WriteLine($"I've added and to the list"); Console.WriteLine($"The list has people in it"); var index = names.IndexOf("Felipe"); if (index == -1) < Console.WriteLine($"When an item is not found, IndexOf returns "); > else < Console.WriteLine($"The name is at index "); > index = names.IndexOf("Not Found"); if (index == -1) < Console.WriteLine($"When an item is not found, IndexOf returns "); > else < Console.WriteLine($"The name is at index "); > names.Sort(); foreach (var name in names) < Console.WriteLine($"Hello !"); > >
Списки других типов
Добавьте следующий код в программу после вызова WorkWithStrings() :
List fibonacciNumbers = [1, 1];
Будет создан список целых чисел. Для первых двух целых чисел будет задано значение 1. Это два первых значения последовательности Фибоначчи. Каждое следующее число Фибоначчи — это сумма двух предыдущих чисел. Добавьте этот код:
var previous = fibonacciNumbers[fibonacciNumbers.Count - 1]; var previous2 = fibonacciNumbers[fibonacciNumbers.Count - 2]; fibonacciNumbers.Add(previous + previous2); foreach (var item in fibonacciNumbers)
Сохраните файл и введите dotnet run , чтобы просмотреть результаты.
Для задач этого раздела вы можете закомментировать код, который вызывает WorkWithStrings(); . Просто поместите два / символа перед вызовом, как показано ниже: // WorkWithStrings(); .
Задача
Попробуйте объединить некоторые идеи из этого и предыдущих занятий. Расширьте код с числами Фибоначчи, который вы создали. Попробуйте написать код для создания первых 20 чисел в последовательности. Подсказка: 20-е число Фибоначчи — 6765.
Выполнение задачи
При каждой итерации цикла суммируются два последних целых числа в списке. Полученное значение добавляется в список. Цикл повторяется, пока в список не будут добавлены 20 элементов.
Поздравляем! Вы выполнили задачи в руководстве по спискам. Можете продолжить изучение дополнительных руководств в своей среде разработки.
Дополнительные сведения о работе с типом List см. в статье Коллекции и структуры данных. Также в нем описаны многие другие типы коллекций.
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Вывод списков
Вывод списков — это одна из стандартных интерфейсных возможностей. Она предоставляется платформой и доступна пользователям любых прикладных решений. С её помощью можно вывести список в табличный или текстовый документ, а затем этот документ вывести на печать или сохранить его в файле на диске. При выводе списка учитывается текущая настройка колонок, отбор и сортировка.
Для вывода списка используется команда Еще — Вывести список…
При выводе списка можно указать набор колонок, которые будут выводиться в документ:
При выводе списка в табличный документ автоматически создаются группировки, если список иерархический. Например, список справочника Номенклатура, выведенный в табличный документ, будет выглядеть следующим образом:
Вывести элементы списка в консоль.
Здравствуйте. Может кто подскажет.
Есть такой код.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
class Program { static void Main(string[] args) { ListMyClass> myList = new ListMyClass>(); myList.Add(new MyClass("Иван", "Морозов")); myList.Add(new MyClass("Семен", "Тарасов")); myList.Add(new MyClass("Петр", "Киселев ")); } } public class MyClass { public MyClass(string name, string secondname) { name = Name; secondname = SecondName } public string Name { get; set; } public string SecondName { get; set; } }
Не получается вывести элементы списка в консоль. В результате в консоли должно быть:
Иван
Морозов
Семен
Тарасов
Петр
Киселев
Запрещено создавать темы с бессмысленными названиями вроде «Помогите!», «Вопрос» и т.п. |
Создавайте темы с осмысленными и понятными названиями — это серьезно повышает шансы, что на ваш вопрос ответят. |
Как вывести список в с
Контейнер list представляет двухсвязный список, то есть такой список, где каждый элемент имеет указатели на предыдущий и последовательный элемент. Благодаря чему мы можем перемещаться по списку как вперед, так и назад. Для использования списка необходимо подключить заголовочный файл list .
#include int main() < std::listlist1; // пустой список std::list list2(5); // список list2 состоит из 5 чисел, каждый элемент имеет значение по умолчанию std::list list3(5, 2); // список list3 состоит из 5 чисел, каждое число равно 2 std::list list4< 1, 2, 4, 5 >; // список list4 состоит из чисел 1, 2, 4, 5 std::list list5 = < 1, 2, 3, 5 >; // список list5 состоит из чисел 1, 2, 4, 5 std::list list6(list4); // список list6 — копия списка list4 std::list list7 = list4; // список list7 — копия списка list4 >
Получение элементов
В отличие от других контейнеров для типа list не определена операция обращения по индексу или функция at(), которая выполняет похожую задачу.
Тем не менее для контейнера list можно использовать функции front() и back() , которые возвращают соответственно первый и последний элементы.
Чтобы обратиться к элементам, которые находятся в середине (после первого и до последнего элементов), придется выполнять перебор элементов с помощью циклов или итераторов:
#include #include int main() < std::listnumbers< 1, 2, 3, 4, 5 >; int first ; // 1 int last < numbers.back() >; // 5 std::cout std::cout
Размер списка
Для получения размера списка можно использовать функцию size() :
std::list numbers< 1, 2, 3, 4, 5 >; int size = numbers.size(); // 5
Функция empty() позволяет узнать, пуст ли список. Если он пуст, то функция возвращает значение true, иначе возвращается значение false:
std::list numbers< 1, 2, 3, 4, 5 >; if (numbers.empty()) std::coutС помощью функции resize() можно изменить размер списка. Эта функция имеет две формы:
- resize(n) : оставляет в списке n первых элементов. Если список содержит больше элементов, то он усекается до первых n элементов. Если размер списка меньше n, то добавляются недостающие элементы и инициализируются значением по умолчанию
- resize(n, value) : также оставляет в списке n первых элементов. Если размер списка меньше n, то добавляются недостающие элементы со значением value
Изменение элементов списка
Функция assign() позволяет заменить все элементы списка определенным набором. Она имеет следующие формы:
- assign(il) : заменяет содержимое контейнера элементами из списка инициализации il
- assign(n, value) : заменяет содержимое контейнера n элементами, которые имеют значение value
- assign(begin, end) : заменяет содержимое контейнера элементами из диапазона, на начало и конец которого указывают итераторы begin и end
Функция swap() обменивает значениями два списка:
std::list list1< 1, 2, 3, 4, 5 >; std::list list2< 6, 7, 8, 9>; list1.swap(list2); // list1 = < 6, 7, 8, 9>; // list2 = < 1, 2, 3, 4, 5 >;
Добавление элементов
Для добавления элементов в контейнер list применяется ряд функций.
- push_back(val) : добавляет значение val в конец списка
- push_front(val) : добавляет значение val в начало списка
- emplace_back(val) : добавляет значение val в конец списка
- emplace_front(val) : добавляет значение val в начало списка
- emplace(pos, val) : вставляет элемент val на позицию, на которую указывает итератор pos. Возвращает итератор на добавленный элемент
- insert(pos, val) : вставляет элемент val на позицию, на которую указывает итератор pos, аналогично функции emplace. Возвращает итератор на добавленный элемент
- insert(pos, n, val) : вставляет n элементов val начиная с позиции, на которую указывает итератор pos. Возвращает итератор на первый добавленный элемент. Если n = 0, то возвращается итератор pos.
- insert(pos, begin, end) : вставляет начиная с позиции, на которую указывает итератор pos, элементы из другого контейнера из диапазона между итераторами begin и end. Возвращает итератор на первый добавленный элемент. Если между итераторами begin и end нет элементов, то возвращается итератор pos.
- insert(pos, values) : вставляет список значений values начиная с позиции, на которую указывает итератор pos. Возвращает итератор на первый добавленный элемент. Если values не содержит элементов, то возвращается итератор pos.
Функции push_back() , push_front() , emplace_back() и emplace_front() :
std::list numbers< 1, 2, 3, 4, 5 >; numbers.push_back(23); // < 1, 2, 3, 4, 5, 23 >numbers.push_front(15); // < 15, 1, 2, 3, 4, 5, 23 >numbers.emplace_back(24); // < 15, 1, 2, 3, 4, 5, 23, 24 >numbers.emplace_front(14); //
Добавление в середину списка с помощью функции emplace() :
std::list numbers< 1, 2, 3, 4, 5 >; auto iter = ++numbers.cbegin(); // итератор указывает на второй элемент numbers.emplace(iter, 8); // добавляем после первого элемента numbers = < 1, 8, 2, 3, 4, 5>;
Добавление в середину списка с помощью функции insert() :
std::list numbers1< 1, 2, 3, 4, 5 >; auto iter1 = numbers1.cbegin(); // итератор указывает на первый элемент numbers1.insert(iter1, 0); // добавляем начало списка //numbers1 = < 0, 1, 2, 3, 4, 5>; std::list numbers2< 1, 2, 3, 4, 5 >; auto iter2 = numbers2.cbegin(); // итератор указывает на первый элемент numbers2.insert(++iter2, 3, 4); // добавляем после первого элемента три четверки //numbers2 = < 1, 4, 4, 4, 2, 3, 4, 5>; std::list values < 10, 20, 30, 40, 50 >; std::list numbers3< 1, 2, 3, 4, 5 >; auto iter3 = numbers3.cbegin(); // итератор указывает на первый элемент // добавляем в начало все элементы из values numbers3.insert(iter3, values.begin(), values.end()); //numbers3 = < 10, 20, 30, 40, 50, 1, 2, 3, 4, 5>; std::list numbers4< 1, 2, 3, 4, 5 >; auto iter4 = numbers4.cend(); // итератор указывает на позицию за последним элементом // добавляем в конец список из трех элементов numbers4.insert(iter4, < 21, 22, 23 >); //numbers4 = < 1, 2, 3, 4, 5, 21, 22, 23>;
Удаление элементов
Для удаления элементов из контейнера list могут применяться следующие функции:
- clear(p) : удаляет все элементы
- pop_back() : удаляет последний элемент
- pop_front() : удаляет первый элемент
- erase(p) : удаляет элемент, на который указывает итератор p. Возвращает итератор на элемент, следующий после удаленного, или на конец контейнера, если удален последний элемент
- erase(begin, end) : удаляет элементы из диапазона, на начало и конец которого указывают итераторы begin и end. Возвращает итератор на элемент, следующий после последнего удаленного, или на конец контейнера, если удален последний элемент
std::list numbers < 1, 2, 3, 4, 5 >; numbers.pop_front(); // numbers = < 2, 3, 4, 5 >numbers.pop_back(); // numbers = < 2, 3, 4 >numbers.clear(); // numbers =<> numbers = < 1, 2, 3, 4, 5 >; auto iter = numbers.cbegin(); // указатель на первый элемент numbers.erase(iter); // удаляем первый элемент // numbers = < 2, 3, 4, 5 >numbers = < 1, 2, 3, 4, 5 >; auto begin = numbers.begin(); // указатель на первый элемент auto end = numbers.end(); // указатель на последний элемент numbers.erase(++begin, --end); // удаляем со второго элемента до последнего //numbers =
- Глава 1. Введение в С++
- Язык программирования С++
- Первая программа на Windows. Компилятор g++
- Первая программа на Windows. Компилятор Clang
- Первая программа на Windows. Компилятор Microsoft Visual C++
- Первая программа на Linux. Компилятор g++
- Первая программа на MacOS. Компилятор Clang
- Настройка параметров компиляции
- Локализация и кириллица в консоли
- Структура программы
- Переменные
- Типы данных
- Константы
- Ввод и вывод в консоли
- using. Подключение пространств имен и определение псевдонимов
- Арифметические операции
- Статическая типизация и преобразования типов
- Поразрядные операции
- Операции присваивания
- Условные выражения
- Конструкция if-else и тернарный оператор
- Конструкция switch-case
- Циклы
- Ссылки
- Массивы
- Многомерные массивы
- Массивы символов
- Введение в строки
- Что такое указатели
- Операции с указателями
- Арифметика указателей
- Константы и указатели
- Указатели и массивы
- Определение и объявление функций
- Область видимости объектов
- Параметры функции
- Передача аргументов по значению и по ссылке
- Константные параметры
- Оператор return и возвращение результата
- Указатели в параметрах функции
- Массивы в параметрах функции
- Параметры функции main
- Возвращение указателей и ссылок
- Перегрузка функций
- Рекурсивные функции
- Рекурсия на примере быстрой сортировки
- Указатели на функции
- Указатели на функции как параметры
- Тип функции
- Указатель на функцию как возвращаемое значение
- Разделение программы на файлы
- Внешние объекты
- Динамические объекты
- Динамические массивы
- unique_ptr
- shared_ptr
- Определение классов
- Конструкторы и инициализация объектов
- Управление доступом. Инкапсуляция
- Объявление и определение функций класса
- Конструктор копирования
- Константные объекты и функции
- Ключевое слово this
- Дружественные функции и классы
- Статические члены класса
- Деструктор
- Структуры
- Перечисления
- Наследование
- Управление доступом в базовых и производных классах
- Скрытие функционала базового класса
- Множественное наследование
- Виртуальные функции и их переопределение
- Преобразование типов
- Динамическое преобразование
- Особенности динамического связывания
- Чистые виртуальные функции и абстрактные классы
- Перегрузка операторов
- Операторы преобразования типов
- Оператор индексирования
- Переопределение оператора присваивания
- Пространства имен
- Вложенные классы
- Обработка исключений
- Вложенные try-catch
- Создание своих типов исключений
- Тип exception
- Типы исключений
- Шаблоны функций
- Шаблон класса
- Специализация шаблона класса
- Наследование и шаблоны классов
- Типы контейнеров
- Вектор
- Итераторы
- Операции с векторами
- Array
- List
- Forward_list
- Deque
- Стек std::stack
- Очередь std::queue
- Очередь приоритетов std::priority_queue
- Множества
- Словарь std::map
- Span
- Определение строк
- Строки с поддержкой Unicode
- Преобразование типов и строки
- Сравнение строк
- Получение подстроки и проверка начала и конца строки
- Поиск подстроки
- Изменение строки
- Операции с символами
- Программа подсчета слов
- Тип std:string_view
- rvalue
- Конструктор перемещения
- Оператор присваивания с перемещением
- Роль noexcept при перемещении
- Объекты функций
- Лямбда-выражения
- Захват внешних значений в лямбда-выражениях
- Шаблон std::function<>
- Минимальный и максимальный элементы
- Поиск элементов
- Копирование элементов
- Удаление элементов и идиома Remove-Erase Idiom
- Сортировка
- Представления. Фильтрация
- Проекция данных
- Пропуск элементов. drop_view и drop_while_view
- Извлечение диапазона элементов. take_view и take_while_view
- Цепочки представлений
- Оператор requires
- Концепты
- Выражение requires
- Ограничения типа для auto
- Базовые типы для работы с потоками
- Файловые потоки. Открытие и закрытие
- Чтение и запись текстовых файлов
- Переопределение операторов ввода и вывода
- Математические константы и операции
- Форматирование строк и функция format
- std::optional
- Управление ресурсами. Идиома RAII
- Идиома копирования и замены
- Идиома Move-and-Swap
- Первая программа в Visual Studio
- Первая программа в Qt Creator