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

Выполнение операций над массивами с использованием вспомогательных методов в C#.

Введение

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

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

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

Цели обучения

В этом модуле вы узнаете как:

  • Сортировать и изменять порядок элементов массива.
  • Очищать и изменять размеры элементов массива.
  • Разбивать строку на массив строк или символов (chars).
  • Объединять элементы массива в строку.

Откройте для себя функции Sort() и Reverse()

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

Создайте массив паллет, затем отсортируйте их

  1. Убедитесь, что у вас открыт Visual Studio и на панели редактора отображается файл Program.cs. Обратите внимание, что файл Program.cs должен быть пустым. Если это не так, выделите и удалите все строки кода.
  2. Введите следующий код в редактор кода Visual Studio
string[] pallets = [ "B14", "A11", "B12", "A13" ];

Console.WriteLine("Sorted...");
Array.Sort(pallets);
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
примечание

В этом примере используется Collection expression syntax, представленный в C# 12.

  1. Уделите минуту просмотру строки Array.Sort(pallets); из предыдущего кода, который вы добавили. Здесь вы используете метод Sort() класса Array для сортировки элементов в массиве в алфавитном порядке.
  2. запустите код. Вы должны увидеть следующий результат
Sorted...
-- A11
-- A13
-- B12
-- B14

Измените порядок расположения поддонов

  1. Чтобы изменить порядок паллет с помощью метода Array.Reverse(), обновите код следующим образом:
string[] pallets = [ "B14", "A11", "B12", "A13" ];

Console.WriteLine("Sorted...");
Array.Sort(pallets);
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}

Console.WriteLine("");
Console.WriteLine("Reversed...");
Array.Reverse(pallets);
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
  1. Сфокусируйтесь на строке кода Array.Reverse(pallets); из предыдущего кода, который вы добавили. Здесь вы используете метод Reverse() класса Array, чтобы изменить порядок элементов.
  2. Сохраните файл с кодом, а затем запустите его с помощью Visual Studio. Вы должны увидеть следующий результат:
Sorted...
-- A11
-- A13
-- B12
-- B14

Reversed...
-- B14
-- B12
-- A13
-- A11

Выводы

Вот несколько важных идей, которые вы рассмотрели в этом разделе:

  • Класс Array имеет методы, которые позволяют манипулировать размером и содержимым массива.
  • Используйте метод Sort() для манипулирования порядком в зависимости от заданного типа данных массива.
  • Используйте метод Reverse() для изменения порядка элементов в массиве.

Изучите функции Clear() и Resize().

Продолжая создавать систему отслеживания паллет для логистической компании, предположим, что вам также нужно отслеживать новые паллеты и удалять старые паллеты из отслеживания. Как создать функциональность отслеживания для добавления и удаления паллет?

Используйте методы массива для очистки и изменения размера массива

Метод Array.Clear() позволяет удалить содержимое определенных элементов массива и заменить его значением по умолчанию. Например, в строковом массиве очищенное значение элемента заменяется на null, а при очистке элемента массива int заменяется на 0 (ноль).

Метод Array.Resize() добавляет или удаляет элементы из вашего массива.

  1. Удалите или используйте оператор комментария строки //, чтобы закомментировать весь код из предыдущих упражнений.
  2. Обновите код в редакторе кода Visual Studio следующим образом:
string[] pallets = [ "B14", "A11", "B12", "A13" ];
Console.WriteLine("");

Array.Clear(pallets, 0, 2);
Console.WriteLine($"Clearing 2 ... count: {pallets.Length}");
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
  1. Уделите минуту внимания строке кода Array.Clear(pallets, 0, 2);. Здесь вы используете метод Array.Clear() для очистки значений, хранящихся в элементах массива pallets, начиная с индекса 0 и очищая 2 элемента.
  2. Запустив код, вы увидите, что значения, хранящиеся в первых двух элементах массива, были очищены. В свойстве Length и операторе foreach элементы все еще существуют, но теперь они пусты.
Clearing 2 ... count: 4
--
--
-- B12
-- A13

Пустая строка в сравнении с null

Когда вы используете Array.Clear(), элементы, которые были очищены, больше не ссылаются на строку в памяти. Фактически, элемент вообще ни на что не ссылается. Указание на ничто - важная концепция, которую поначалу бывает трудно понять. Что, если попытаться получить значение элемента, на который повлиял метод Array.Clear(), вы сможете это сделать?

Доступ к значению очищенного элемента

Для определения значения очищенного элемента необходимо использовать два подхода, чтобы увидеть, как компилятор C# работает с нулевым значением.

  1. Вставьте новые строки кода вокруг строки Array.Clear(pallets, 0, 2); следующим образом:
Console.WriteLine($"Before: {pallets[0]}");
Array.Clear(pallets, 0, 2);
Console.WriteLine($"After: {pallets[0]}");
  1. Проверьте, чтобы ваш код соответствовал следующему листингу:
string[] pallets = [ "B14", "A11", "B12", "A13" ];
Console.WriteLine("");

Console.WriteLine($"Before: {pallets[0]}");
Array.Clear(pallets, 0, 2);
Console.WriteLine($"After: {pallets[0]}");

Console.WriteLine($"Clearing 2 ... count: {pallets.Length}");
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
  1. Сохраните файл кода, а затем запустите его с помощью Visual Studio. Вы должны увидеть следующий результат:
Before: B14
After:
Clearing 2 ... count: 4
--
--
-- B12
-- A13

Если вы сосредоточитесь на строке вывода After: , можно подумать, что значение, хранящееся в pallets[0], является пустой строкой. Однако компилятор C# неявно преобразует нулевое значение в пустую строку для представления.

Вызов метода-помощника строки на очищенном элементе

Чтобы доказать, что значение, хранящееся в pallets[0] после очистки, равно null, измените пример кода так, чтобы вызвать метод ToLower() для pallets[0]. Если это строка, то все должно работать нормально. Но если это null, то код должен выбросить исключение.

  1. Чтобы вызывать метод ToLower() при каждой попытке записать pallets[0] в консоль, обновите код следующим образом::
Console.WriteLine($"Before: {pallets[0].ToLower()}");
Array.Clear(pallets, 0, 2);
Console.WriteLine($"After: {pallets[0].ToLower()}");
  1. Убедитесь, что ваш код соответствует следующему листингу:
string[] pallets = [ "B14", "A11", "B12", "A13" ];
Console.WriteLine("");

Console.WriteLine($"Before: {pallets[0].ToLower()}");
Array.Clear(pallets, 0, 2);
Console.WriteLine($"After: {pallets[0].ToLower()}");

Console.WriteLine($"Clearing 2 ... count: {pallets.Length}");
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
  1. Сохраните файл кода, а затем используйте Visual Studio для запуска кода. На этот раз при запуске кода вы увидите большое сообщение об ошибке. Если вы разберете текст, то увидите следующее сообщение:
System.NullReferenceException: Object reference not set to an instance of an object.

Это исключение возникает потому, что попытка вызвать метод для содержимого элемента pallets[0] происходит до того, как компилятор C# успевает неявно преобразовать null в пустую строку.

Мораль этой истории заключается в том, что Array.Clear() удалит ссылку элемента массива на значение, если таковое существует. Чтобы исправить это, вы можете проверить наличие null перед попыткой вывести значение.

Чтобы избежать ошибки, добавьте оператор if перед обращением к элементу массива, который потенциально может быть нулевым.

if (pallets[0] != null)
Console.WriteLine($"After: {pallets[0].ToLower()}");

Изменение размера массива для добавления новых элементов

Далее переделайте листинг кода из Шага 1, включив в него код для изменения размера массива. После завершения работы ваш код должен соответствовать следующему листингу кода:

string[] pallets =  ["B14", "A11", "B12", "A13" ];
Console.WriteLine("");

Array.Clear(pallets, 0, 2);
Console.WriteLine($"Clearing 2 ... count: {pallets.Length}");
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}

Console.WriteLine("");
Array.Resize(ref pallets, 6);
Console.WriteLine($"Resizing 6 ... count: {pallets.Length}");

pallets[4] = "C01";
pallets[5] = "C02";

foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
  1. Уделите несколько минут тому, чтобы сосредоточиться на строке Array.Resize(ref pallets, 6);.

Здесь вы вызываете метод Resize(), передавая массив pallets по ссылке, используя ключевое слово ref. В некоторых случаях методы требуют передачи аргументов по значению (по умолчанию) или по ссылке (с использованием ключевого слова ref). Причины, по которым это необходимо, требуют долгого и сложного объяснения того, как осуществляется управление объектами в .NET. К сожалению, это выходит за рамки данного модуля. Если вы сомневаетесь, рекомендуем обратиться к Intellisense или Microsoft Docs за примерами того, как правильно вызывать тот или иной метод.

В данном случае вы изменяете размер массива паллет с четырех элементов до 6. Новые элементы добавляются в конец текущих элементов. Два новых элемента будут нулевыми, пока вы не присвоите им значение.

  1. Сохраните файл кода, а затем используйте Visual Studio для запуска кода. При выполнении кода вы должны увидеть следующий результат.
Clearing 2 ... count: 4
--
--
-- B12
-- A13

Resizing 6 ... count: 6
--
--
-- B12
-- A13
-- C01
-- C02

Изменение размера массива для удаления элементов

И наоборот, вы можете удалить элементы массива с помощью Array.Resize().

  1. Обновите свой код в редакторе кода Visual Studio следующим образом:
string[] pallets = [ "B14", "A11", "B12", "A13" ];
Console.WriteLine("");

Array.Clear(pallets, 0, 2);
Console.WriteLine($"Clearing 2 ... count: {pallets.Length}");
foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}

Console.WriteLine("");
Array.Resize(ref pallets, 6);
Console.WriteLine($"Resizing 6 ... count: {pallets.Length}");

pallets[4] = "C01";
pallets[5] = "C02";

foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}

Console.WriteLine("");
Array.Resize(ref pallets, 3);
Console.WriteLine($"Resizing 3 ... count: {pallets.Length}");

foreach (var pallet in pallets)
{
Console.WriteLine($"-- {pallet}");
}
  1. Сохраните файл кода, а затем используйте Visual Studio для запуска кода. При выполнении кода вы должны увидеть следующий результат:
Clearing 2 ... count: 4
--
--
-- B12
-- A13

Resizing 6 ... count: 6
--
--
-- B12
-- A13
-- C01
-- C02

Resizing 3 ... count: 3
--
--
-- B12

Обратите внимание, что вызов Array.Resize() не удалил первые два нулевых элемента. Скорее, он удалил три последних элемента. Примечательно, что последние три элемента были удалены, даже если они содержали строковые значения.

Можно ли удалить нулевые элементы из массива?

Если метод Array.Resize() не удаляет пустые элементы из массива, есть ли другой вспомогательный метод, который выполнит эту работу автоматически? Нет. Лучшим способом удаления пустых элементов из массива будет подсчет количества ненулевых элементов путем итерации по каждому элементу и инкрементирования переменной (счетчика). Затем создается второй массив, размер которого равен размеру переменной счетчика. И наконец, пройдитесь циклом по каждому элементу исходного массива и скопируйте ненулевые значения в новый массив.

Выводы

Вот несколько важных идей, которые вы изучили в этом разделе:

  • Используйте метод Clear(), чтобы удалить значения из элементов массива.
  • Используйте метод Resize(), чтобы изменить количество элементов в массиве, удаляя или добавляя элементы из конца массива.
  • Новые элементы массива и очищенные элементы являются нулевыми, то есть они не указывают на значение в памяти.

Откройте для себя Split() и Join()

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

Чтобы выполнить преобразование данных, вам нужно принять входящие данные в виде строки, разобрать их на более мелкие элементы, а затем изменить их в соответствии с требуемым форматом. Как разобрать строковые данные на более мелкие элементы?

Методы массива для типа данных String

Переменные типа string имеют множество встроенных методов, которые преобразуют одну строку либо в массив меньших строк, либо в массив отдельных символов.

При обработке данных, полученных из других компьютерных систем, иногда они отформатированы или закодированы таким образом, что не подходят для ваших целей. В таких случаях вы можете использовать методы Array типа данных string, чтобы разобрать строку в массив.

Используйте функцию ToCharArray() для инвертирования строки

  1. Удалите или используйте оператор комментария строки //, чтобы закомментировать весь код из предыдущих упражнений.
  2. Обновите код в редакторе кода Visual Studio следующим образом
string value = "abc123";
char[] valueArray = value.ToCharArray();

Здесь вы используете метод ToCharArray() для создания массива char, каждый элемент которого содержит один символ исходной строки.

Переверните, а затем объедините массив символов в новую строку

Далее вы меняете порядок символов в массиве, а затем с помощью метода Write объединяете их в один вывод.

  1. Обновите код в редакторе кода Visual Studio следующим образом:
string value = "abc123";
char[] valueArray = value.ToCharArray();
Array.Reverse(valueArray);
string result = new string(valueArray);
Console.WriteLine(result);

Выражение new string(valueArray) создает новый пустой экземпляр класса System.String (что соответствует типу данных string в C#) и передает в качестве конструктора массив char.

  1. Вы должны увидеть следующий результат
321cba

Объедините все символы в новую строку значений, разделенных запятыми, с помощью функции Join().

Возможно, вам нужно разделить каждый элемент массива char запятой, как это часто бывает при работе с данными, представленными в виде ASCII-текста. Для этого вы закомментируете строку кода, добавленную в шаге 2, и воспользуетесь методом Join() класса String, передав в него символы, которыми вы хотите отделить каждый сегмент (запятую), и сам массив.

  1. Обновите код в редакторе кода Visual Studio следующим образом:
string value = "abc123";
char[] valueArray = value.ToCharArray();
Array.Reverse(valueArray);
// string result = new string(valueArray);
string result = String.Join(",", valueArray);
Console.WriteLine(result);
  1. Сохраните файл кода, а затем запустите его с помощью Visual Studio. Вы должны увидеть следующий результат:
3,2,1,c,b,a

Split() строку значений, разделенных запятыми, на массив строк

Чтобы завершить код, вы используете метод Split(), предназначенный для переменных типа string, чтобы создать массив строк.

  1. С помощью редактора кода Visual Studio добавьте следующие строки кода в нижнюю часть файла:
string[] items = result.Split(',');
foreach (string item in items)
{
Console.WriteLine(item);
}
  1. Уделите минуту просмотру предыдущего кода.

Запятая передается в .Split() в качестве разделителя, чтобы разделить одну длинную строку на более мелкие. Затем в коде используется цикл foreach для итерации по каждому элементу вновь созданного массива строк, items.

  1. Проверьте, что теперь ваш код выглядит следующим образом:
string value = "abc123";
char[] valueArray = value.ToCharArray();
Array.Reverse(valueArray);
// string result = new string(valueArray);
string result = String.Join(",", valueArray);
Console.WriteLine(result);

string[] items = result.Split(',');
foreach (string item in items)
{
Console.WriteLine(item);
}
  1. Сохраните файл кода, а затем запустите его с помощью Visual Studio Code. При запуске кода вы увидите следующий результат:
3,2,1,c,b,a
3
2
1
c
b
a

Массив items, созданный с помощью string[] items = result.Split(',');, используется в цикле foreach и отображает отдельные символы из исходной строки, содержащейся в переменной value.

Выводы

Вот несколько моментов, которые следует помнить при работе со строками и массивами:

  • Используйте такие методы, как ToCharArray() и Split(), чтобы создать массив.
  • Используйте такие методы, как Join(), или создайте новую строку, передав в нее массив char, чтобы превратить массив обратно в одну строку.

Общее задание. Выполните задание на перестановку слов в предложении

Задачи с кодом закрепляют пройденный материал и помогают обрести уверенность перед тем, как продолжить работу.

Много раз вам придется объединять несколько идей, рассмотренных в этом модуле, в одно решение. Вам следует разложить большую проблему на множество мини-проблем, а затем использовать различные идеи из этого модуля для решения каждой мини-проблемы.

Напишите код, чтобы перевернуть каждое слово в сообщении

  1. Выберите и удалите все строки кода в редакторе кода Visual Studio.
  2. Обновите код в редакторе кода Visual Studio следующим образом:
string pangram = "The quick brown fox jumps over the lazy dog";
  1. Напишите код, необходимый для перестановки букв каждого слова местами и отображения результата.

Другими словами, не просто переверните каждую букву в переменной pangram. Вместо этого вам нужно будет перевернуть только буквы в каждом слове, но вывести перевернутое слово в исходное положение в сообщении.

Ваш код должен выдавать следующий результат:

ehT kciuq nworb xof spmuj revo eht yzal god
warning

Это сложная задача. Вам нужно будет объединить многие концепции, изученные в этом упражнении, включая использование Split(), ToCharArray(), Array.Reverse() и String.Join(). Вам также нужно будет создать несколько массивов и хотя бы один оператор итерации.

Удачи! Продолжайте декомпозировать задачу на маленькие шаги, а затем решайте конкретный шаг, прежде чем переходить к следующему.

Общее задание. Выполните задание по разбору строки заказов, сортировке заказов и пометке возможных ошибок

Данные бывают разных форматов. В этой задаче вам нужно разобрать отдельные «ID заказа» и вывести отсортированные «ID заказа» с пометкой «Ошибка», если они не содержат ровно четыре символа.

  1. Выделите и удалите все строки кода в редакторе кода Visual Studio.
  2. В Visual Studio добавьте следующий код, чтобы получить данные для задачи
string orderStream = "B123,C234,A345,C15,B177,G3003,C235,B179";
  1. Обратите внимание, что в предыдущем коде переменная orderStream содержит строку из нескольких идентификаторов заказов, разделенных запятыми
  2. Добавьте код под предыдущим кодом, чтобы разобрать "Идентификаторы заказов" из строки входящих заказов и сохранить "ID заказов" в массиве
  3. Добавьте код для вывода каждого "ID заказа" в отсортированном порядке и помечайте заказы, длина которых не равна четырем символам, как "- Ошибка".
  4. Сохраните и запустите свой код Ваш код должен выдать следующий результат
A345
B123
B177
B179
C15 - Error
C234
C235
G3003 - Error

Заключение

В этом модуле вы выполнили упражнения с использованием вспомогательных методов для более эффективного использования массивов:

  • Очистить элементы массива, узнав, что их значение равно null, с помощью метода Array.Clear().
  • Изменение размера массива для добавления и удаления элементов с помощью метода Array.Resize().
  • Преобразование строки в массив с помощью метода String.Split() с указанием символа-разделителя строк для получения значения в возвращаемом массиве.
  • Объединить все элементы массива в одну строку с помощью метода String.Join().

Вспомогательные методы массивов позволяют гибко работать с данными в приложениях. Без этих функций массивы были бы менее полезны.