Приветствую всех, сегодня рассмотрим решение, интересной задачи. Дан массив чисел, который передается в метод в виде IEnumerable, метод должен распарсить текс, разделив строку по пробелу на числа, и передать числа в конструктор другого класса в виде List<Point>
Посмотрим условие задачи:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public static void Main() { foreach (var point in ParsePoints(new[] { "1 -2", "-3 4", "0 2" })) Console.WriteLine(point.X + " " + point.Y); foreach (var point in ParsePoints(new List<string> { "+01 -0042" })) Console.WriteLine(point.X + " " + point.Y); Console.ReadKey(); } public class Point { public Point(int x, int y) { X = x; Y = y; } public int X, Y; } |
И дан метод который необходимо сформировать под условие задания:
1 2 3 4 5 |
public static List<Point> ParsePoints(IEnumerable<string> lines) { return lines. } |
Мы знаем что для разделения строки по символу можем использовать метод Split, соответственно реализуем запрос Linq
1 2 |
lines .Select(x => x.Split()) |
Разберемся что же тут происходит, у нас берется каждый элемент строки который разделяется по пробелу, при чем его не обязательно указывать, так как по умолчанию разделения в Split именно пробел. Но мы могли бы и так написать Split(‘ ‘), что то же не является ошибкой. Далее у нас формируется массив строк содержащие только цифры с арифметическими знаками.
Следующей задачей у нас стоит передать в конструктор эти числа по координатам. Посмотрим на класс Point, в нем конструктор который принимает два числа int int , и передает их полям. Давайте создадим такой запрос который создавал ссылку на класс и передавал туда значения:
1 |
.Select(x => new Point(.. , ..) |
Но что мы будем передавать в конструктор если мы имеем массив строк, а он ожидает числа, Для этого мы воспользуемся методом Parse которые произведет каст «преобразование» из string в int и передасть уже числа. Еще одной из не мало важной проблемы у нас является то, что мы должны передать элементы по индексу. А сделать это можно с помощью метода First() и Last(). Который позволит возвратить первый и последний элемент массива. Последнее предложение будет:
1 |
.Select(x => new Point(int.Parse(x.First()),int.Parse( x.Last()))) |
Теперь нам лишь остается, все это поместить в коллекцию, для этого воспользуемся методом ToList(); На этом мы и решили поставленную задачу.
А что делать если бы конструктор класса Point принимал не два числа, а три и более?
Как передать значение массива по индексу c использованием LINQ и лямбда-выражением?
Если бы такое задание было и наш конструктор принимал 3 числа, на бы пришлось передавать значения по индексу, и методы First Last тут бы нам не помогли, так как они передают только первый и последний элемент массива. В этом случаи нам пришлось бы указать индекс явно. Вот как бы это выглядело:
1 |
.Select(x => new Point(int.Parse(x[0]),int.Parse( x[1]), int.Parse(x[2]) |
По аналогии можно было передать по индексу и 4, 5 и более чисел в конструктор Point если бы это требовалось.