Если бы нам пришлось выполнять упражнение по суммированию массивов, о котором мы говорили, на JavaScript, а не на C #, сколько решений мы могли бы придумать? Очевидно, что решение цикла for из Части 1 будет работать в JavaScript.

Конечно, два связанных решения из этой статьи, использующие goto и указатели, не сработают. В JavaScript есть ярлыки, но их нельзя использовать для подобных целей. И если бы у JavaScript был доступ к указателям, Интернет, вероятно, не пережил бы 90-е годы.

Решение foreach из Части 2 также будет работать примерно так же, используя for..of.

И, вероятно, было бы довольно легко придумать решение на основе итератора, подобное тому, что описано в этой статье.

Как вы, возможно, уже думаете, конструкцию for..of в JavaScript можно упростить.

Давайте немного разберемся в этом. Почему values имеет доступный forEach метод? Потому что во время выполнения values (мы предполагаем) будет содержать массив. Современный JavaScript имеет довольно внушительный набор методов, доступных для обработки массивов. Фактически, мы можем еще немного упростить этот пример, используя другой метод массива.

Однострочные FTW!

Вы действительно можете делать с reduce много удивительных вещей, в том числе некоторые действительно умные вещи, которые сделают ваш код непонятным для следующего человека, который взглянет на него, а вы, возможно, будете через шесть месяцев, так что будьте осторожны! Но такой вид использования в точности соответствует цели reduce, а именно, взять набор вещей и свести их к единственному экземпляру той же самой вещи. Параметры - это «аккумулятор» (который при необходимости можно инициализировать конкретным значением) и «текущее» значение. Тело функции просто описывает, как объединить «текущее» значение с «аккумулятором», в данном случае путем сложения двух вместе.

Совокупный

Современный C # также имеет довольно впечатляющий набор методов, доступных для обработки наборов (видите, что я там делал?). В предыдущей статье я упоминал, что интерфейс IEnumerable является важной концепцией C #. Причина? Все, что реализует IEnumerable, имеет доступ ко всем методам расширения, доступным в классе Enumerable. И это настоящий список!

Фактически, один из этих методов - это версия array.reduce для .NET, которая называется Aggregate.

Ужасно похоже на версию JavaScript, да? И так же, как reduce в JavaScript, Aggregate можно использовать для всех видов добра и зла. Каждый раз, когда у вас есть «IEnumerable» вещей - чисел, строк, дат, виджетов и т. Д. - вы можете использовать Aggregate, чтобы превратить этот вектор в скаляр, превратить это множество в индивидуальное, чтобы объединить некоторые или все эти части в единое целое, используя любую применимую логику преобразования.

Сумма

Для сравнения, скромный метод Sum кажется довольно слабым. Aggregate может принимать практически любую коллекцию объектов и делать с ними что угодно; Sum может принимать только числа, и все, что он умеет, - это складывать их. Хромой!

В Части 1 я потратил некоторое время, рассказывая о том, как мне нравится использовать это в качестве упражнения по кодированию для собеседований с программистами. Как я уже сказал, большинство людей придумывают цикл for. Но особые замечания для горстки тех, кто инстинктивно придумывает это решение:

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

Но можем ли мы рассчитывать на то, что это будет работать так же хорошо, как ручной алгоритм сложения целых чисел? Наверное, может, кто знает? Вероятно, в 99,99% случаев это не имеет значения. Может быть, в вашем наборе целых чисел (мощность? Распределение? ???) есть что-то уникальное или необычное, что можно оптимизировать с помощью другого подхода. И, возможно, ваша проблема с целочисленным сложением наглядно представляет собой длинный полюс в критичном для производительности фрагменте кода. Хорошо, делай то, что тебе нужно делать. Но прежде чем реализовать что-то более сложное, я сначала сделаю простую вещь, а затем измерю ее, чтобы доказать, что простой подход не работает.

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

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

С другой стороны, для разработчика, чей первый инстинкт звучит так: «Готов поспорить, я мог бы написать рекурсивный метод для этого», по крайней мере, будет интересное интервью. Тем не менее, хотя это может быть не лучший подход для этого решения, рекурсия по-прежнему является ценной концепцией для понимания программиста. В следующий раз мы рассмотрим несколько рекурсивных решений.