LINQ 'em all!

Иногда технологии развиваются. Иногда они развиваются быстро. Гораздо быстрее, чем система образования. Гораздо быстрее, чем пишутся книги. Слишком быстро.

Когда-то программист без знания ассемблера не являлся программистом. Потом, таковой программист уже не считался программистом (в кругу тех, кто ассемблер знал). Потом знание ассемблера уже перестало быть необходимым для того, чтобы считаться (и по факту являться) программистом. Теперь, с развитии кроссплатформенных технологий, на ассемблерах реализуется лишь очень узкий (сравнительно с оставшимся набором задач) круг задач, связанных с железом.

Это нормально. Время меняется. Автомобили сменяют кэбы, гребной винт вытеснил парус, патрон похоронил стрелу. Устаревшие технологии становятся уделом энтузиастов и узких профессионалов в тех немногих сферах, где без них нельзя. Кто следующий?

В ИТ — это подход к программированию через написание алгоритмов. Т.е., те многочисленные умные слова и бесчисленные задачи, которые мы с вами решали на первых курсах университетов, и которыми нашим студентам до сих пор усиленно забивают голову. Почему пришел их черед уходить в небытие? Да просто потому что задачи, решаемые с помощью циклов, условий, рекурсии и прочих алгоритмических трюков, расписанных Д.Кнутом в знаменитом трехтомнике, в их большинстве можно решить с помощью современных средств разработки без собственно алгоритмов. Грамотное владение ООП (т.е. то, чему надо учить студентов в программистских ВУЗах прежде всего) в сочетании с современными технологиями позволяет красиво и эффективно избавиться от огромного количества кодострочек. Как?

Пример.
Дан текстовый файл с двумерным целочисленным массивом. Необходимо считать массив, упорядочить строки по возрастанию минимального элемента в них и вывести в другой файл результирующий массив. Именно такие задачи решают в школе и на первых курсах, не так ли?

Вход
1,3,5,7,8
4,6,7,4,2
8,3,5,7,8
0,4,3,2,1
3,7,5,9,0
1,4,8,9,3
8,3,5,6,7
4,0,2,3,7

Выход (должен быть)
0,4,3,2,1
3,7,5,9,0
4,0,2,3,7
1,3,5,7,8
1,4,8,9,3
4,6,7,4,2
8,3,5,7,8
8,3,5,6,7

Вариант первый. Классический.
class Program
 {
 static List<List> _Numbers = new List<List>();
 static String _source = "source.txt";
 static String _output = "output.txt";

static void Main(string[] args)
 {
 Console.WriteLine("Расположить строки в порядке убывания минимального элемента в них");
 //Считывание данных из файла
 TextReader tr = File.OpenText(_source);
 String s = tr.ReadLine();

while (s != null)
 {
 _Numbers.Add(new List());
 foreach (String sIntNumber in s.Split(','))
 {
 _Numbers.Last().Add(Convert.ToInt32(sIntNumber));
 }
 s = tr.ReadLine();
 }
 Console.WriteLine("Исходник считан");
 tr.Close();

//Собственно, сортировка
 for (int i = _Numbers.Count - 1; i > 0; i--)
 {
 for (int j = 0; j < i; j++)
 {
 if (GetMinNumber(_Numbers[j]) > GetMinNumber(_Numbers[j + 1]))
 {
 _Numbers.Reverse(j, 2);
 }
 }
 }
 Console.WriteLine("Сортировка закончена");

//Вывод в файл
 StreamWriter sw = File.CreateText(_output);
 sw.WriteLine("Классика не устаревает!");
 foreach (List subarray in _Numbers)
 {
 String sOutput = "";
 foreach (int i in subarray)
 {
 sOutput = sOutput + i.ToString() + ",";
 }
 sw.WriteLine(sOutput.Substring(0,sOutput.Length - 1));
 }
 sw.Close();
 Console.WriteLine("Результат выведен в файл");
 Console.ReadLine();
 }

// Нахождение минимального значения строки массива
 static int GetMinNumber(List aRow)
 {
 int iMin = aRow[0];
 for (int i = 1; i < aRow.Count; i++)
 {
 if (aRow[i] < iMin)
 {
 iMin = aRow[i];
 }
 }
 return iMin;
 }
 }

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

А теперь - Just LINQ it!
<code> class Program
 {
 static String _source = "L:\\Проекты\\тренировка\\п1\\linqemall\\linqsource.txt";
 static String _output = "L:\\Проекты\\тренировка\\п1\\linqemall\\linqoutout.txt";

static void Main(string[] args)
 {
 Console.WriteLine("Расположить строки в порядке убывания минимального элемента в них"); 
 //Считывание из файла
 TextReader tr = File.OpenText(_source);
 String sFullFile = tr.ReadToEnd();
 String[] lRows= sFullFile.Split('\n');
 tr.Close();
 Console.WriteLine("Считан файл с исходником!");

//Сортировка
 var qLinqed = from oneRow in lRows
 orderby
 (from s in oneRow.Split(',') select Convert.ToInt32(s)).Min()
 select oneRow;
 Console.WriteLine("Произвели сортировку!");

//Вывод данных
 var qToOut = from oneString in qLinqed
 select oneString + "\n" ;
 String sToOut = String.Concat(qToOut.ToArray());
 TextWriter sw = File.CreateText(_output);
 sw.WriteLine("Мы сLINQовали это!");
 sw.Write(sToOut);
 sw.Close();
 Console.WriteLine("Данные записаны в файл!");
 Console.ReadLine();
 }
 }


Нравится? Мечта студента: ни одного цикла или условия (хотя, не скажу, что LINQ — это просто). Но, дело не в LINQ. Дело лишь в том, что использование современной на настоящий момент технологии позволило сберечь время, зрение, нервы и мозговые потуги программиста для достижения благой и светлой цели. Какой? Ну, хотя бы соблазнить вон ту сногсшибательную брюнетку, цокающую каблучками по заснеженному тротуару…
Так, зачем тратить время на те принципы программирования, которые давно уже не являются мейнстримом? Зачем писать кучу кода, если ее можно не писать (кэп на связи)?
Мораль сей басне — не в LINQ и не в брюнетке. А в том, что современный подход к обучению программированию в школах и ВУЗах — устарел. А значит, его надо менять. И прежде всего менять его надо тем, кто сейчас учит(ся) программированию.

Искренне Ваш Фламберг.


0 комментариев

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.