Содержание
Кортеж — это относительно новый тип данных 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.