Пишем LINQ на JavaScript с нуля

Зачем


Однажды при разработке компонента графика для веб-браузера мы столкнулись с проблемой обработки последовательностей на JavaScript.

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

Естественно, хотелось бы иметь аналогичные возможности и на JavaScript.

На данный момент существует немало реализаций LINQ для JavaScript, например, linq.js, $linq. Эти реализации предоставляют широкие возможности, сравнимые с реализацией на C#. Обратной стороной является немалый размер кода, из которого в конкретном приложении может использоваться лишь небольшая часть. Например, нам необходима лишь функция distinct, а мы вынуждены добавлять килобайты кода third-party библиотеки.

Опять же, любопытно разобраться, как же конкретная библиотека работает, а разбирать исходный код большой библиотеки зачастую утомительно. Или в нашем случае у нас уже есть своя библиотека для JavaScript и мы лишь хотим её компактно дополнить функционалом работы с последовательностями.

Насколько пригоден JavaScript для реализации


Определимся с элементами JavaScript, которые необходимы для реализации задуманого. У нас есть массивы, есть лямбда-функции, есть объекты, возможно наследование с некоторыми оговорками. Мы хотим выполнять операции, представленные лямбда-функциями над данными, содержащимися в массивах и эти операции мы хотим сгруппировать в объекте. Всё в порядке.

Попробуем сами


Начнём с определения необходимых сущностей.
Очевидно, что для работы с последовательностями самым базовым объектом является итератор. Всё, что от него нужно, это три метода:
  • moveNext() перемещает указатель на следующий элемент и возвращает true в случае успеха и false, если следующего элемента нет (достигнут конец последовательности);
  • current() возвращает текущий элемент либо null, если такого элемента нет (достигнут конец последовательности);
  • reset() перемещает указатель на первый элемент последовательности.

Значит, нам нужен метод, конструирующий итератор из базовой последовательности (например, из массива JS).

Далее нам нужен объект, который будет содержать набор методов для работы с множествами (where, select и т.д.). Поскольку больше хотелось иметь название, отражающее суть функционала, чем “намекать” на аналоги, было выбрано слово Walkable (суть такой, по элементам которого можно “ходить”/итерироваться). Каждый метод этого объекта должен возвращать тоже объект Walkable, чтобы поддерживать возможность объединять несколько вызовов в одной цепочке (другими словами, чтобы можно было передавать результат исполнения предыдущего метода на вход следующему).

Во-вторых, нам нужен источник данных. Не хотелось бы ограничиваться встроенным массивом JS в качестве единственного источника. Вот здесь нам и пригодится упомянутый выше итератор. Всё, что нам нужно от последовательности, это единственный метод, возвращающий итератор (конечно, каждый раз новый экземпляр, чтобы его можно было использовать, не изменяя состояние других итераторов). На следующем шаге к такому объекту можно “подмешать” методы Walkable и в итоге над результатом можно вызывать любые методы Walkable и каскадировать их в произвольные цепочки.

Проиллюстрируем теорию кодом. Вот метод, создающий объект Walkable из массива JS:

var arrayWalkable = function(arr) {
      var walker = function() { .// внутрення функция-конструктор итератора
        var idx = -1; // состояние итератора
        // далее классические методы итератора
        this.reset = function() { idx = -1; };
        this.moveNext = function() { return (++idx < arr.length); };
        this.current = function() { return (idx < 0 || idx >= arr.length) ? null : arr[idx]; }; 
      };
      // создаём обёртку над массивом, возвращающую итератор
      var walkable = { getWalker: function() { return new walker(); },};
      // расширяем обёртку методами объекта Walkable
      // WAVE.extend - базовая функция нашей библиотеки, при желании можно реализовать/скопировать         
      //свою
      WAVE.extend(walkable, WAVE.Walkable); 
      return walkable;
    }

Далее займёмся собственно объектом Walkable. Он должен содержать методы работы с последовательностями, каждый из которых должен возвращать в свою очеред новый объект Walkable.

Итак, реализуем объект Walkable и самый популярный метод where. Поскольку мы выбрали walkable в качестве названия, то и все методы расширения мы называем с буквы “w”:

wWhere: function(filter) {
                	var srcWalkable = this;
                	var walkable = {
                  	  getWalker: function() {
                      	    var walker = srcWalkable.getWalker();
                    	    return {
                      	      reset: function() { walker.reset(); },
                      	      moveNext: function() {
                        	  while (walker.moveNext()) {
                          	    var has = filter(walker.current());
                          	    if (has) return true;
                        	  }
                        	  return false;
                      	      },
                      	      current: function() { return walker.current(); }
                    	    };
                  	  }  
                	}
                	WAVE.extend(walkable, WAVE.Walkable);
                	return walkable;
    	}, //wWhere

В качестве аргумента для wWhere принимаем функцию filter, которая в свою очередь принимает на вход элемент последовательности и возвращает true или false (включать или нет элемент в результат). Далее запоминаем this в переменной srcWalkable (классический приём в JS).

На следующем шаге по аналогии с вышеописанным методом arrayWalkable определяем базовый объект walkable с ключевым методом getWalker. При каждом вызове получаем новый итератор текущего объекта, чтобы не влиять на другие итераторы. И возвращаем объект.

Затем переопределяем в соответствии с логикой операции where методы итератора:
  • reset: просто вызывает reset источника последовательности (например, это может быть объект, произведённый методом WAVE.arrayWalkable, описанным выше;
  • moveNext: вызывает moveNext источника последовательности, пока не найдёт элемент, удовлетворяющий критерию filter, либо пока не достигнет конца исходной последовательности;
  • current: вызывает current источника последовательности.

Пример использования


В качестве простейших примеров использования можно привести фрагменты юнит-тестов.

Продемонстрируем работу самого итератора и Walkable:

Легко видеть, что такой дизайн позволяет выстраивать произвольные функции, возвращающие Walkable, в цепочки произвольной длинны.

По аналогии с wWhere реализуются остальные функции нашей библиотеки, например, wSelect, wDistinct и т.д.

function() {
          var a = [1, 2, 3, 4, 5]; 

          var aw = WAVE.arrayWalkable(a);

          var walker = aw.getWalker(), i=0;
          while(walker.moveNext()) {
            assertTrue(a[i] === walker.current());
            i++;
          }

          assertFalse(walker.moveNext());
          assertTrue(null === walker.current());
     }

Теперь используем wWhere, выстроив их в цепочку:

function() {
          var a = [1, 2, 3, 4, 5]; 

          var aw = WAVE.arrayWalkable(a);
          var wWhere1 = aw.wWhere(function(e) { return e > 1; });
          var wWhere2 = wWhere1.wWhere(function(e) { return e < 5; });
          var result2 = wWhere2.wToArray();

          for(var i in result2) log(result2[i]);

          assertTrue( 3 === result2.length);
     }

В коде использованы функции-обёртки для тестирование, включённые в wv.js.

Выводы


Реализация собственной LINQ-подобной библиотеки на JavaScript не является сложной задачей и каждый желающий с минимальными знаниями программирования может с ней справиться.

Тем не менее, по нашему опыту, подобная библиотека очень здорово упрощает написание основанной на работе с сериями данных логики, при этом занимая в коде ровно столько места, сколько функций нам от неё необходимо.

Исходный код библиотеки может быть получен тут, юнит-тесты находятся тут.
П.С:
Решил добавить полный список функций Walkable:
wSelect, wSelectMany, wWhere, wAt, wFirst, wFirstIdx, wCount, wDistinct, wConcat, wExcept, wGroup, wGroupIntoObject, wGroupIntoArray, wGroupAggregate, wOrder, wTake, wTakeWhile, wSkip, wAny, wAll, wMin, wMax, wAggregate, wSum, wEqual, wToArray, wEach, wWMA (moving average), wHarmonicFrequencyFilter (наш собственный фильтр, концепция зарекомендовала себя отлично, например, здесь), wConstLinearSampling, wSineGen, wSawGen, wSquareGen, wRandomGen,
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 72

    +3
    1) лично я ни разу не сталкивался в js с необходимостью обработать коллекцию, которой ещё нет целиком, т.к. в JS, по крайней мере в браузере, нет никаких потоковых апи. Вы не можете начать обрабатывать ответ от сервера раньше чем он будет полностью получен, поэтому необходимость работы с коллекциями в «поточном» стиле, с помощью итераторов выглядит немного надуманной. Сделаем из массива итератор, и потом из итератора массив.
    2) с обычными массивами кажется лучшее, по возможности, использовать встроенные функции filter (==Where), some (==Any), every (==All), map (==Select) и другие, потому что они быстрее. Хорошо бы набросать на jsperf тест и сравнить с вашими, но кажется что нативные выйграют. Возможно ваши будут побеждать на очень больших коллекциях, т.к. не создается промежуточных коллекций, но кажется что этот выйгрыш будет только на очень-очень-очень больших массивах.
    3) таких библиотек уже очень много, не совсем ясно зачем делать еще одну.
      0
      1) Пока мы обрабатываем как раз коллекции, ктр. в браузере уже есть. Но это не исключает использование коллекций, ктр. ещё полностью нет, а смастерить конструкцию, ктр. будет возвращать результат несколькими порциями, не составляет принципиальной сложности. В любом случае, спасибо за идею, мы даже как-то не задумывались над таким сценарием использования
      2) а) для обычных массивов и простых операций — возможно. Но если нужна, скажем, агрегация, то встроенные не решат всех проблем.
      б) хотелось иметь реализацию, использующую «консервативные» конструкции JS во избежания всяких пролем с совместимосью
      3) Вы, безусловно, правы насчёт существования множества других похожих библиотек. Однако я объяснил причины своей реализации в самом начале статьи. Могу разве что добавить, что ключевая идея нашего фрэймворка NFX — Unistack, т.е. своё решение от начала до конца, пусть даже это будет напоминать изобретение велосипеда. Наш опыт говорит, что такая философия — самая выгодная в долгосрочной перспективе.
        +3
        для обычных массивов и простых операций — возможно. Но если нужна, скажем, агрегация, то встроенные не решат всех проблем.

        Любая агрегация делается через reduce. Собственно, есть ровно три с половиной операции, необходимых для реализации практически любых операций над множествами данных: reduce, map, filter, mapFlat.

        хотелось иметь реализацию, использующую «консервативные» конструкции JS во избежания всяких пролем с совместимосью

        Ну так полифиллы вам в помощь.
          +2
          mapFlat -> flatMap
            0
            да все можно, вопрос только в простоте практического применения
            например тут:
            github.com/aumcode/serbench/blob/master/Source/Serbench/WebViewer/views/OverviewCharts.htm#L79-115
              0
              (Особенно, конечно, поведение Distinct доставляет. Ну да ладно.)

              А чем, скажите, ваши wSelect и wEach проще в применении стандартных map и forEach?
                0
                ничем, однако оно даёт универсалность обработки разних данных, например
                как такое сделать?
                github.com/aumcode/nfx/blob/master/Source/NFX.Wave/Templatization/StockContent/Embedded/script/wv.utest.htm#L2726-2771

                уравниваем самплинг
                github.com/aumcode/nfx/blob/master/Source/NFX.Wave/Templatization/StockContent/Embedded/script/wv.utest.htm#L2886-2901
                  +1
                  Из ваших тестов не понятно, какое именно надо сделать.

                  (и да, есть у меня подозрение, что вот для того, что у вас там проглядывается, надо брать Rx)
                    0
                    как такое сделать?

                    Желательно такое не делать никак. Вы зачем-то вынесли в стандартную библиотеку работы с коллекциями метод который:
                    1) кажется делает какую-то достаточно специфичную обработку, которая нужна явно «не каждый день»
                    2) работает только с коллекцией определенного формата. Тоесть я могу сделать
                    Walkable.fromJs([1,2,3]).wWMA()
                    

                    И это будет валидный код, только странный, потому что метод wWMA подразумевает конкретный формат коллекции на входе. Такие методы нужно выносить в отдельные библиотеки
                    3) очень странно называется и принимает коллекцию имеющую однобуквенные названия.

                    Что же касается вашего вопроса, я склонен считать, что можно переписать вашу обработку на стандартных функциях работы с массивами, и она скорее всего будет быстрее вашей.
              +1
              1) использование итераторов приобретает смысл в основном только при необходимости работы с не загруженными до конца коллекциями, когда их полная загрузка в память тяжела или невозможна (обработать 100тб данных например), либо при комбинировании цепочек обработки, т.к. не нужно создавать промежуточных коллекций. Обрабатывать плоские массивы итераторами выглядит странным, потому что вы платите за сложный доступ к элементу с помощью вызова метода итератора, вместо простой адресации массива, но не получаете за это ничего.

              Чтобы использовать загрузку данных по кусками, у вас метод getNext должен возвращать промис, иначе не понятно что делать итератору, в ситуации когда коллекция ещё не завершена, но её продолжение ещё не доступно, и соответственно все методы должны работать с промисами, и быть асинхронными. Это ещё один большой оверхед который вы заплатите ни за что.

              Итого единственная ситуация где вы возможно выигрываете, это обработка большой коллекции большим количеством последовательных операций. Но такой код лучше переписать, так, чтобы операция были сложные, но мало, с использованием map/reduce, и, кажется, в этой ситуации вы снова проиграете.
              2) а) приведите пожалуйста пример выборки которую нельзя сделать с помощью map\reduce? Вроде бы к ним сводится почти все
              б) более правильно заполифилить методы Array.filter/map/reduce/etc которые уже нативно поддерживаются в большинстве даже мобильных браузеров. Единственный где их нет, это IE <= 8, но его доля уже не так велика (мягко говоря), можно заполифилить.
              3) ваше конечно право, но тратить деньги на то, чтобы переписывать то, что уже давно есть в bower кажется странным. Селекторы вы тоже свои написали или querySelector всетаки используете?
            0
            На С# запрос выглядит много интересней:
            var result = a.Where(x => x > 1 && x < 5).ToArray();
              0
              Согласен, но, как Вы понимаете, в JS это просто так работать не будет. Была идея с неким промежуточным языков предикатов для Walkable, однако мы решили от неё отказаться в силу несоответствия сложности возможной выгоде.
                +1
                Конкретно пример выше идеально реализуется на массивах через .filter.
                +3
                linqjs.codeplex.com

                var queryResult2 = Enumerable.From(jsonArray)
                    .Where("$.user.id < 200")
                    .OrderBy("$.user.screen_name")
                    .Select("$.user.screen_name + ':' + $.text")
                    .ToArray();
                
                  0
                  Почему тогда не github.com/Reactive-Extensions/RxJS или подобная библиотека?
                    0
                    У Reactive философия все-таки другая, с observables/promises еще надо научиться работать надо.
                      0
                      У Reactive прекрасная филофия, попробоваши раз, уже не остановить =)
                        +1
                        Ну, вы в этот угол можете свою философию не продавать, тут уже распробовали.
                      0
                      Новедь! это подход к обработке событий. Мне кажется, это немного другое.
                      0
                      Ваш код не будет делать тоже, что и код в примере статьи.
                        0
                        Я и не претендовал на работающий код к статье. :)
                        Это пример из мануала самого фреймворка, наглядно показывающий возможности, которые вы запросили.
                          0
                          Обычно в мануале разработчики ставят самые яркие примеры, чтобы привлечь внимание. Я пользовался этой библиотекой и поверьте там все совсем не так прекрасно.
                            0
                            Будем рады, если распишите pros & cons.
                        0
                        а если нужно заюзать существующую внешнюю функцию в предикате?
                          0
                          Ну, мне кажется, просто передаёте её аргументом, не?
                      +2
                      lodash.com можно использовать модульно.
                        –1
                        не буду спорить, но там как минимум другой стиль.
                        + не сочтите параноиком, но что делать, если:
                        — это проект перестанет поддерживаться, а нужна будет критическая модификация (придётся либо разбираться в этом коде досконально либо избавляться от него в пользу другого 3rd-party)?
                        — какая лицензия в предложенной библиотеке?
                          +1
                          Там все довольно просто написано, лицензию можете глянуть на github
                            0
                            На гитхабе лицензия формата «можно все», если я ничего не попутал.
                              0
                              необязательно, вопрос лицензирования — ещё тот «pain in ass», как-то потратил несколько часов на разбирательство, но всех ответов не получил.
                              и даже если «можно всё», то что с поддержкой — непонятно (точнее понятно, что ненадёжно)
                                +2
                                Что «необязательно»? Вы конкретный текст лицензии уже прочитали, чтобы так говорить?
                                  0
                                  Тоесть вы считаете лучше все самим переписать, вместо того чтобы потратить несколько часов на разбирательство с лицензией?
                                    0
                                    дело в комплексном подходе.
                                    Walkable исползуется в 100 мест в разних компонентах огромнои системы.
                                    Для того чтобы что-то «слепить» пару раз конечно не нужно.

                                    это как — стоит ли там хонде или ниссану самому делать сидения для машин
                                      +2
                                      Она используется в 100 местах огромной системы, потому что вы так решили, а не потому что она лучше. Так тот факт, что вы её используете в 100 местах вообще не аргумент ни за что. И если уж на то пошло, то underscore используется в гораздо большем количестве мест.

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

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

                                      Аналогии чаще всего врут и вводят в заблуждение, но если вам так нравится, давайте поиграем в эту игру.
                                      Стоит ли хонде или ниссану изобрести новую резьбу для болтов и использовать нестандартные размеры для головок болтов и гаек?
                                        0
                                        это как — стоит ли там хонде или ниссану самому делать сидения для машин

                                        Все аналогии врут.

                                        The [Honda] Integra Type R comes equipped with Recaro seats, four-piston Brembo front brakes…

                                        (Wiki, сайт производителя)
                                          0
                                          вам ничего не продают, мы делимся опытом.
                                          если вы считаете что вас обманули в чем-то, зачем тогда писать комментарии вообше не по теме.
                                          вы прекрасно понимаете сравнение с производителями авто и дисскутировать это нет смысла.

                                          если вам РЕАЛьНО интересно зачем мы делаем так как мы делаем, задайте конкретние вопросы и ПРОЧИТАЙте внимательно ответ.

                                          а так я с вами на 1000% процентов согласен — все ето никому не надо, вообще ничего никому не надо и уэ все есть в тои или инои форме
                                            –1
                                            Да вы уже писали, почему вы так делаете — потому что вы считаете, что знаете как лучше.
                                              0
                                              посмотрите на это. займет реално 3 минути внимания.

                                              github.com/aumcode/serbench

                                              я не успел ещо опыбликоват реzултаты — сами их получите на своеи машине

                                              там все тесты ПРОТИВ НФХ, там все заточено под других производителей.

                                              это реалная работа, понимаете? возмите и запустите. там все будет видно на екране компа.

                                              если вам реално интересно. этот тул именно для скептиков, первые — это мы сами.
                                                0
                                                А там где-нибудь есть тест «сколько бы мы это писали на lodash/RxJS»?
                                                  +1
                                                  Мы тут вроде про LINQ на JS разговариваем, а вы предлагаете, на сколько я понял за 3 минуты, сравить .NET сериализаторы в JSON? Это сейчас к чему вообще?

                                                  Но если хотите давайте поговорим про них, только выложите пожалуйста какие-нибудь графики сюда, я к сожалению не хочу запускать у себя бинарник непонятного происхождения, да и вообще сижу под убунтой.
                                                0
                                                Да ладно вам, обижаться. Как-то несолидно, честное слово. Нам тут всем РЕАЛЬНО интересно зачем вы это делаете. Но на все вопросы по сути вопроса, вы не отвечаете, и никаких аргументов не приводите, кроме того, что вы считаете что использовать готовые библиотеки опасно, т.к. Not invented here.

                                                Я вам например уже выдал тезис: ваша реализация проигрывает в скорости и потреблении памяти стандартной библиотеке и не имеет по большому счету никаких преимуществ. Вы мне кроме ниссана и хонды ничего не ответили.
                                                    0
                                                    Так у вас там, дайте я угадаю, поток событий в реальном времени на самом деле?
                                                      0
                                                      yes, server processes steady 100,000 msg/sec using NFX Glue + Erlang.OTP

                                                      Generates JSON payload which is fed to client via NFX.Wave server, client workls over a buffer of around 5-10K summaries that the user may visually adjust (find harmonics, apply EMA, edd noise etc..) they see it in chart

                                                      is this the most efficient solution? no it is not. the most efficient one would have been rewriting all in WPF/C# on the client, but it does its job very well.
                                                        –1
                                                        Так что ж вы RxJS-то не взяли, который для этого заточен (и расширяем любыми операциями, какие вам хочется)?
                                                        0
                                                        строго говоря, js не выполняется на системах реального времени
                                                        0
                                                        Вы сейчас кому вообще отвечали?

                                                        Давайте я сделаю еще одну попытку достучаться до вашего сердца.

                                                        Приведите пожалуйста какой-нибудь аргумент, чем реализация какой-либо обработки массива с помощью walkable лучше чем реализация той же самой обработки на Array.map/reduce/filter?

                                                        Если хотите, давайте выберем один алгоритм и сравнием на jsPerf вашу реализацию и более нативную?

                                                        Аргумент в моем понимании это утверждение, а не кусок кода. Например
                                                        — мы считаем что вот это работает быстрее чем на нативных функциях
                                                        — мы считаем что так писать код понятнее
                                                        — whatever else
                                                          –2
                                                          я только за!
                                                          возмите и сравните наш случай который описан выше (про трайдинг)

                                                          уверен что у нас будет все медленее а может и нет, насколько — посмотрим
                                                          однако если вы наидете и порекоммендуете ускорение — бyдем очен признательны
                                                    0
                                                    Brilliant!
                                              0
                                              sorry, but it appears that mostly people have no clue what a license means in the context of a «civilized world».
                                              The OpenSource licenses are very much liable to err when there is dough involved…
                                                0
                                                А вы уже ознакомились с конкретной обсуждаемой лицензией, или это так, общее-наболевшее?
                                            –1
                                            Простите меня но сейчас 2015 на дворе есть гитхаб. Лицензия как минимум MIT.

                                            — это проект перестанет поддерживаться, а нужна будет критическая модификация (придётся либо разбираться в этом коде досконально либо избавляться от него в пользу другого 3rd-party)?

                                            Это не 3rd-party — это стандарт для разработчиков на JS. В текущий момент lodash и underscore самые популярные библиотеки их применение показывает ваше умение. Кроме того если внимательно следить за гитом 2х этих библиотек люди чтобы сделать PR должны предоставить пачку тестов +JSPerf. Поэтому код в них крайне, крайне быстр и достаточно покрыт тестами. Велосипед выше который — не тестируем, не предсказуем, и крайне опасен для продакшена.

                                            Как идея для постижения JS вполне себе ничего.
                                              +1
                                              >> Это не 3rd-party — это стандарт для разработчиков на JS. В текущий момент lodash и underscore самые популярные библиотеки
                                              >> применение показывает ваше умение. Кроме того если внимательно следить за гитом 2х этих библиотек люди чтобы сделать PR должны >>предоставить пачку тестов +JSPerf
                                              как я писал неоднократно и в самой статье, и в комментах, мы избегаем вводить в свой фрэймворк чужой исходный код.
                                              отдельные библиотеки как таковые могут быть просто великолепны, однако, их совместное использование часто вызывает концептуальные и стилистические несоответсвия и код превращается в мешанину.
                                              >> Велосипед выше который — не тестируем, не предсказуем, и крайне опасен для продакшена.
                                              на чём вы основываетесь, говоря, что «велосипед» нетестируем?
                                                0
                                                как я писал неоднократно и в самой статье, и в комментах, мы избегаем вводить в свой фрэймворк чужой исходный код.
                                                отдельные библиотеки как таковые могут быть просто великолепны, однако, их совместное использование часто вызывает концептуальные и стилистические несоответсвия и код превращается в мешанину.


                                                Ага я заметил в вашей чудо библиотеке undefined в одном случае у вас string в одном обьект с этим проблем конечно нет сравнения верные но красотой кода и ее стилистикой даже не пахнет начиная от названий пременых заканчивая названиями функций обработчиков ошибок.

                                                Перфоманс нулевой если у вас
                                                for(var i=0; i<name.length; i++)
                                                ...
                                                

                                                Серьезно? Вы знали что в цикле использование name.length это заведомое обращение к обьекту N раз?
                                                А что нативный forEach и map при некоторых условиях быстрее в разы чем обычный for? ( Особенно заметно на webkita'х ).

                                                У вас даже стайлгайда нету, о каком стиле вы говорите может об этом ?
                                                var srcWalkable = this;
                                                

                                                и буквально ниже
                                                var self = this;
                                                

                                                Это каша из функций которая писать для нее тесты у меня желания не возникает. Там собраны десяток УЛЬТА полезных функций которые есть в lodash и underscore. Математический аппарат я не оцениваю нет сил и времени разбираться.

                                                ES2015 Generators и код этой библиотеки можно выкинуть.

                                                Кроме того существуют вещи которые просто вводят в ступор в JS. Вот пример вам :
                                                ...
                                                obj.method();
                                                ...
                                                

                                                и
                                                (null,obj.method)()
                                                

                                                В некоторых случаях это дает прирост почти от ~2% — 10% на webkit'ах но на ~15% медленнее в IE 11. И если это сортировка там 1000000 маркеров по некому критерию то я сделаю так чтобы в одном случае получить прирост на 10% а в другом остаться на текущей производительности.
                                                  0
                                                  >>Ага я заметил в вашей чудо библиотеке undefined в одном случае у вас string в одном обьект с этим проблем конечно нет сравнения >>верные но красотой кода и ее стилистикой даже не пахнет начиная от названий пременых заканчивая названиями функций >>обработчиков ошибок
                                                  не сочтите за грубость, но я иногда затрудняюсь читать Ваши комментарии без знаков препинания )

                                                  >> У вас даже стайлгайда нету, о каком стиле вы говорите может об этом?
                                                  естественно, нету, и, смею надеятся, не будет )

                                                  >>ES2015 Generators и код этой библиотеки можно выкинуть.
                                                  выкидывайте, дорогой mr47, ни в чём себе не отказывайте )
                                                    0
                                                    >> Ага я заметил в вашей чудо библиотеке undefined в одном случае у вас string в одном обьект с этим проблем конечно нет сравнения >> верные но красотой кода и ее стилистикой даже не пахнет начиная от названий пременых заканчивая названиями функций >
                                                    >>обработчиков ошибок.

                                                    Вы не могли бы подсказать, где у нас «undefined» является объектом?
                                                      0
                                                      Выкидывайте, дорогой mr47, ни в чём себе не отказывайте.
                                                      Денег на нормального фронтендщика нет так бы и сказали.

                                                      Вы не могли бы подсказать, где у нас «undefined» является объектом?

                                                      Вот прямо сейчас откройте консоль и напишите
                                                      var und = "undefined";
                                                      var k = undefined;
                                                      console.log(typeof k===und); // у вас так часто но есть и == (не строгое сравнение)
                                                      

                                                      Такой код будет работать но, всегда есть это «НО»:
                                                      k === und // false
                                                      ....
                                                      ...
                                                      k === undefined // true
                                                      

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

                                                      И это далеко не придел фантазии а если попробовать
                                                      "".split().length // 1
                                                      "".split("").length // 0
                                                      

                                                      И это далеко не самые большие странности…

                                                      Не пишите больше на javascript. Пишите больше но — осмысленно. А лучше наймите хорошего фронтендера/джаваскриптера он вам все объяснит.
                                                      PS: я не буду оценивать уровень вашего текущего фронтендщика и есть он есть вообще, но отсутствие модульности, самой простой системы сборки (grunt, gulp, броколи и прочие) не говоря уже об webpack. Это крайне печально пару лет назад писали вот так вот не зная об AMD, Commonjs и прочего новомодного (imports из es2015).

                                                      Пожелаю вам удачи. Ведь она самое главное :)
                                                        0
                                                        >> Денег на нормального фронтендщика нет так бы и сказали.
                                                        Вы любите считать чужие деньги? )

                                                        >>>>Вы не могли бы подсказать, где у нас «undefined» является объектом?
                                                        ответа на заданый вопрос я не получил,

                                                        >>я не буду оценивать уровень вашего текущего фронтендщика и есть он есть вообще, но отсутствие модульности, самой >>простой системы сборки (grunt, gulp, броколи и прочие) не говоря уже об webpack. Это крайне печально пару лет назад писали >>вот так вот не зная об AMD, Commonjs и прочего новомодного (imports из es2015).
                                                        собственно, никто и не просил об оценке )
                                                          0
                                                          ответа на заданый вопрос я не получил
                                                          И не получите, я же не буду за вас делать вашу работу. Я и так вас бесплатно проконсультировал в вопросах фронтенда на текущий момент.
                                                          Вы любите считать чужие деньги? )
                                                          А никто и не считал, я просто констатировал очевидное из вашего кода. И собственно вы же это делали для ультробыстрогосервевера который обрабатывает аж 100000000 запросов в секунду. Странно куда у вас делись средства. Да не суть.
                                                          собственно, никто и не просил об оценке )
                                                          Тогда этому не место на хабре.
                                                          Используйте свой бложек или жжчку.

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


                                                          Ваши логика из 2004 наверное когда не было гита как токового когда не было кучи кода который бери используй. И все стремились писать и собирать свои собственные библиотеки супер функций которые постоянно дополняются и обновляются из проекта в проект.А сейчас 2015 прошу проснуться пока еще не поздно. Клиент конечно как мамонт не вымрет но явно с таким качеством ограничит вас — что и хорошо :)

                                                          PS: Как один из тех кто пытался достучатся до вас двоих, аккуратно объясняя суть, вводя в современный фронтенд.

                                                          Желаю вам — удачи.
                                                            0
                                                            >>И не получите, я же не буду за вас делать вашу работу. Я и так вас бесплатно проконсультировал в вопросах фронтенда >>на текущий момент.
                                                            Вы обвинили нас в том, что не можете подвердить

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

                                                            >>Ваши логика из 2004 наверное когда не было гита как токового когда не было кучи кода который бери используй. И все >>стремились писать и собирать свои собственные библиотеки супер функций которые постоянно дополняются и >>обновляются из проекта в проект.А сейчас 2015 прошу проснуться пока еще не поздно. Клиент конечно как мамонт не >>вымрет но явно с таким качеством ограничит вас — что и хорошо :)
                                                            Вы думаете, что логика так сильно меняется за 11 лет? )
                                                            По-моему, кто хочет, использует готовые компоненты, кто не хочет, не использует.
                                                            Повторюсь, статья и была адресована тем, кто хочет сделать свои.

                                                            >>Желаю вам — удачи.
                                                            Спасибо, Вам абсолютно искренне того же

                                                              0
                                                              Вы думаете, что логика так сильно меняется за 11 лет? )

                                                              Вообще — да. По крайней мере, ей лучше бы меняться, потому что индустрия меняется.
                                                                0
                                                                как по мне — так не поменялось ничего вообще со времен кнута и жекстры.
                                                                да компутеры стали в 1000 раз быстрее+SSD+networking етц. однако как хранили 10,000,000 записеи в 1997 годы в оракле
                                                                так и сегодня (vertical software) — тол'ко сегодня все виснет и сплошине ошибки :) — конечно мне и всем осталним программистам это
                                                                выгодно когда береш /hour но когда работаеш на себя — совсем другая картина.

                                                                а впрочем мало что изменилось — тот кто грамотный мыслитель сможет написать в 2015 хоть на Борланд ТП хоть на Руби —

                                                                а вообще все эти споры о чем-то непонятно о чем. расскажите лучше что есть у вас, киньте ссылку.
                                                                например вы набросились на г-на визарда за его статию — а ведь это реально круто работает в массе прикладных задач.
                                                                не нравится — не берите, но намного болше хотелось бы увидеть что делаете вы и как — а мы бы позаимствовали ваш опыт
                                                                  0
                                                                  однако как хранили 10,000,000 записеи в 1997 годы в оракле так и сегодня

                                                                  Сегодня десять миллионов записей — это рутина. Я за несколько месяцев написал систему, которая (на одном сервере, без особых оптимизаций) порождает порядка миллиона записей в месяц, если не быстрее. В соседнем посте люди обрабатывают миллион записей в минуту. И это все — рутина.

                                                                  например вы набросились на г-на визарда за его статию — а ведь это реально круто работает в массе прикладных задач.

                                                                  Да много, что круто работает в массе прикладных задач, только вынося это решение на публику, надо быть готовым услышать, что есть решения лучше. Какие? Вам показали.
                                                  0
                                                  how many times have you owned a software company in the US and been sued for licensing violations?
                                                  MIT = means nothing
                                                  when you sell your IP, lawyers do a due diligence on you, that is when EVERY LIBRARY that you use is going to open
                                                  a potential legal case, and transform to $10-20K of hiring legal counsel with technical background to deliver the statement of IP validity
                                                    0
                                                    Просто оставлю это здесь.
                                                    THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
                                                      0
                                                      this means absolutely nothing. and obviously you have no background in law interpretation.

                                                      funny, Serge Alaynikov who has just been acquitted today after 4 years of legal battle,
                                                      — acquitted for the 2nd time — as this VIOLATES the constitution and double jeopardy law.

                                                      he has been sued EXACTLY for this — he posted code under MIT and Apache while at Goldman,
                                                      the code that HAS BEEN opensource for 10 years — he spent in jail almost a year. go google him up bro
                                                        0
                                                          0
                                                          Эта история идиотизм более того он же работал в банковской системе. Вот скажите почему компания joynet не подала в суд на контребьюторов io.js?

                                                          Или почему гугл пользуется jquery как и тысячи сайтов совершенно бесплатно? Причем я не слышал о громких делах связных с jquery.

                                                          Это идиомы, 20000$ в банковских системах — ничто. Я не собираюсь с вами спорить о лицензиях и об открытом ПО.

                                                          И стоило бы написать на языке ресурса.
                                                            0
                                                            people get sued daily. you just don't know about it.
                                                            the moment you start making money — you will get sued. This is how society works.

                                                            I have personally sold code on numerous occasions, every time whoever buys your code will execute a complete investigation
                                                            what they are buying. I agree with you — this is laughable, but it is how it works.
                                                            An average technical attorney charges $500/hr in New York.
                                                            To read your code base (even if it uses JQuery, Angular, MySQL) — they will charge at the very least 10 hrs investigation +
                                                            2 hrs admin time, so here you are at $6,000 bill.

                                                            The case of Serge — I know personally, our common friend was in court. The accusations that have been set — are completely contradictory to what the LICENSING terms of EXISTING code showed, the code existed BEFORE Goldman. The case was 100% fabricated form day 1.

                                                            This is just an illustration. I was trying to explain that licensing does not really protect companies when someone wants to push them
                                                              0
                                                              Сергея скорей всего посадили за типичную лицензию MIT. Но опять же тут вопрос к юристам. А вообще лучше использовать уже готовые лицензии больших проектов например .

                                                              Facebook много платит своим юристам чтобы подобного не было. Просто иногда стоит подумать дважды когда работаешь на людей которые орудуют миллионами — особенно банки.
                                                                0
                                                                Oh, srsly.

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

                                                                Во-вторых… я несколько раз продавал и покупал код, иногда у вполне себе международных компаний. Никакого complete investigation не было.
                                                                В-третьих, если вам верить, то этот ваш поверенный все равно будет читать ваш код, вне зависимости от того, используете вы сторонние библиотеки, или нет. Так почему бы их не использовать?

                                                                В одном вы правы: сам по себе факт лицензии не защищает вас, если кто-то хочет до вас докопаться, и чем крупнее тот, кто до вас докапывается, тем вам тяжелее. Но в этом случае вас вообще ничего не защищает, кроме адвоката. Продали свой и исключительно свой код? Получите иск за его повторную продажу (или несанкционированное включение)
                                                +1
                                                Вопрос зачем, когда есть RxJS и подобные, на крайний случай underscore/lodash сойдет.

                                                (underscore)
                                                _.chain([1,2,3,1])
                                                  .filter(function(i){
                                                     return i>2
                                                  })
                                                  .value();
                                                


                                                А если уже совсем сложные вещи и концепция Rx/Promise/callback-hell не подходит GraphQL или подобные вещи вам в помощь.

                                                Хотя по большому счету в ES2015 есть и генераторы/интераторы и прочие прелести зачем изобретать?

                                                (Не относится к автору.)

                                                PS: Не тормози babel-ни!

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

                                                Самое читаемое