Содержание
Кортеж — это относительно новый тип данных C# (появился в C# 7.0), который предоставляет краткий синтаксис для группирования нескольких элементов данных в упрощенную структуру. Кортежи позволяют сгруппировать и предоставить пользователю данные различных типов. Сегодня поговорим о том, как можно использовать кортежи в своих приложениях C#.
Определение и инициализация кортежа в C#
Для того, чтобы определить кортеж в C# можно использовать следующее описание:
(типы_элементов_через_запятую) Имя_кортежа;
То есть, вначале в круглых скобках указываем через запятую типы данных для элементов кортежа, а затем — имя кортежа. Например:
(int, double, string) tuple;
Таким образом, мы объявили кортеж, состоящий из трех элементов — целого числа, числа с плавающей запятой и строки.
Чтобы инициализировать кортеж, мы также должны использовать круглые скобки:
tuple = (1, 1.2, "Hello world");
Так, выше мы объявили кортеж с именем tuple
и инициализировали его, присвоив каждому элементу соответствующее значение. Теперь мы можем обратиться к элементам кортежа следующим образом:
int i = tuple.Item1; Console.WriteLine(i);
Здесь мы присвоили переменной i
значение первого элемента кортежа. Можно и напрямую вывести любой элемент кортежа в консоль, например, так:
Console.WriteLine(tuple.Item3);
Item1
, Item2
, Item3
и так далее — это имена полей кортежа, которые создаются автоматически. Чтобы добраться до любого элемента кортежа, достаточно написать его имя, поставить точку и в выпадающем списке выбрать необходимых элемент. Но, согласитесь, что Item1
и так далее — не совсем удобные имена? Что скрывается за tuple.Item1
— знает только сам разработчик и то, может через день забыть. Поэтому, при определении кортежа мы можем сами указывать имена полей, например:
(int Count, double Summ, string Hello) tuple; tuple = (1, 1.2, "Hello world"); int i = tuple.Count; Console.WriteLine(i); Console.WriteLine(tuple.Hello);
В приведенном выше примере мы объявили кортеж с тремя элементами и каждому элементу определили свое собственное имя. Теперь мы можем использовать понятные имена элементов кортежа.
Как использовать кортежи в C#
Одним из наиболее распространенных способов использования кортежей является получение нескольких значений при вызове метода. Когда мы рассматривали методы C#, то для получения нескольких значений из своего метода мы придерживались такого правила — одно значение возвращается в результате метода (через оператор return
), а все последующие — через параметры с модификатором out
. Такой подход вполне может быть. А можно использовать для возврата необходимых значений кортеж. Чтобы продемонстрировать использование кортежа, напишем пример сортировки массива различными методами, например, возьмем сортировку выбором, пузырьковую и вставками. Пусть наша программа будет оценивать работу каждого алгоритма по следующим параметрам: количество сравнений и количество итераций в циклах.
Вторая программа — сортировка массива различными методами
Теперь мы уже знаем как использовать собственные методы в C# и даже немного улучшили нашу первую программу сортировки массива, написав вспомогательный метод для вывода массива в консоль. Теперь, используя кортежи, мы ещё немного улучшим наше приложение и «научим» его сортировать массив различными способами и выводить основные результаты сортировки в виде кортежа. Во-первых, так как мы будем сортировать массив различными способами, то нам потребуется вот такое перечисление (enum
):
enum Method { Select, Bubble, Insertion }
определяющее метод сортировки: выбором, пузырьком и вставками. Теперь, напишем методы, в которых будет сортироваться массив. Я приведу только один из методов — сортировку выбором, как выглядят другие методы — можно посмотреть по приведенным выше ссылкам:
static (int, int) SelectSort(int[] array) { int indx; int count = 0; //общее количество итераций цикла int permut = 0;//количество перестановок for (int i = 0; i < array.Length; i++) { indx = i; count++; for (int j = i; j < array.Length; j++) { if (array[j] < array[indx]) { indx = j; } count++; } if (array[indx] == array[i]) continue; Swap(array, i, indx); permut++; } return (count, permut); }
Здесь Swap
— это вспомогательный метод, меняющим местами два элемента массива:
static void Swap(int[] array, int i, int j) { int temp = array[i]; array[i] = array[j]; array[j] = temp; }
Обратите внимание на результат, возвращаемый методом SelectSort
— это кортеж состоящий из двух элементов с целочисленным типом int
. Внутри метода объявлены две переменные — count
и permut
, которые по мере работы цикла наращиваются и, в итоге передаются через оператор return
в виде кортежа:
return (count, permut);
Аналогичным образом написано ещё два метода: BubbleSort
для сортировки пузырьком и InsertionSort
— для сортировки вставками. Все три метода возвращают кортеж.
Чтобы не загружать основной метод программы лишними инструкциями, напишем один метод, который будет сортировать массив:
static void SortArray(string[] input, Method method) { int[] array = GetArray(input); Console.WriteLine("\r\nНесортированный массив:"); PrintArray(array); (int Count, int Permutations) Result; switch (method) { case Method.Select: { Result = SelectSort(array); Console.Write($"\r\nСортировка выбором: итераций цикла {Result.Count}; Перестановок {Result.Permutations}"); break; } case Method.Bubble: { Result = BubbleSort(array); Console.Write($"\r\nСортировка пузырьком: итераций цикла {Result.Count}; Перестановок {Result.Permutations}"); break; } case Method.Insertion: { Result = InsertionSort(array); Console.Write($"\r\nСортировка вставками: итераций цикла {Result.Count}; Перестановок {Result.Permutations}"); break; } } Console.Write("\r\nОтсортированный массив:"); PrintArray(array); }
На входе метод получает массив строк (то, что введет пользователь в консоли). Внутри метода используется ещё один вспомогательный метод GetArray
, который преобразует массив строк в массив целых чисел:
static int[] GetArray(string[] strArray) { int[] intArray = new int[strArray.Length]; for (int i = 0; i < strArray.Length; i++) { intArray[i] = int.Parse(strArray[i]); } return intArray; }
Чтобы нам было в дальнейшем удобнее работать с результатами методов сортировки был объявлен кортеж с именованными полями:
(int Count, int Permutations) Result;
Ну, а далее, в зависимости от того, какое значение перечисления enum Method
передается в метод, происходит сортировка массива и вывод результатов в консоль. Таким образом, остается только написать несколько строк в методе Main
нашей программы:
Console.WriteLine("Введите через запятую целые числа и нажмите Enter"); string[] nums = Console.ReadLine().Split(new char[] { ',' }); SortArray(nums, Method.Select); SortArray(nums, Method.Bubble); SortArray(nums, Method.Insertion);
Результат работы программы может выглядеть вот так:
9,8,7,6,5,4,3,2,1
Несортированный массив: 9 8 7 6 5 4 3 2 1
Сортировка выбором: итераций цикла 54; Перестановок 4
Отсортированный массив: 1 2 3 4 5 6 7 8 9
Несортированный массив: 9 8 7 6 5 4 3 2 1
Сортировка пузырьком: итераций цикла 45; Перестановок 36
Отсортированный массив:1 2 3 4 5 6 7 8 9
Несортированный массив: 9 8 7 6 5 4 3 2 1
Сортировка вставками: итераций цикла 44; Перестановок 36
Отсортированный массив:1 2 3 4 5 6 7 8 9
Как видите, используя кортежи мы можем получать в результате работы метода не одно, а несколько значений. Кстати, код представленной выше программы можно сделать ещё более коротким и избавиться от лишних вызовов Console.Write()
, если возвращать кортеж, содержащий три элемента (третий элемент — название метода сортировки), но этот момент пусть останется нам в качестве домашнего задания.
Итого
Сегодня мы познакомились с таким типом данных как кортежи C#. Используя кортежи можно обеспечивать возврат методом нескольких значений без использования параметров с модификатором out, а также представлять данные различных типов в виде упрощенных структур. Пример, рассмотренный в статье можно найти в нашем репозитории на Github.