ЙажаСценарий / Говнокод #19692 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
module.exports = leftpad;
function leftpad (str, len, ch) {
  str = String(str);
  var i = -1;
  if (!ch && ch !== 0) ch = ' ';
  len = len - str.length;
  while (++i < len) {
    str = ch + str;
  }
  return str;
}

Мама, мама, я написал Модуль для NodeJS!!!

Запостил: gost gost, (Updated )

Комментарии (41) RSS

  • А добавлять пробелы по одному слева в цикле, это для JS программистов нормально?
    Ответить
    • У меня тоже бомбануло от кода, когда статью на кабре прочитал.
      Миллионы скачиваний, "абсракция", и ни один JS-адепт не обратил внимания на то, что алгоритм квадратичный.
      В теории, конечно, для больших строк паддинг врядли кто-то будет вызывать, не узкое место, но в модуле из ОДНОЙ ФУНКЦИИ, КАРЛ можно было и не за квадрат реализовать.
      Ответить
      • Ну строки же в ж.скрипте не такие, как в сишке. Конкатенация у них O(1), это потом, если например распечатать надо, то будет O(ln n).
        Ответить
        • Да, похоже, в FF используют Ropes. Не нашёл гарантий O(1)... Верёвки обычно балансировать надо, иначе доступ по индексу тормозной будет, поэтом в худшем случае должно быть O(log N) на конкатенацию.

          В V8 какая-то другая оптимизация для конкатенаций в цикле.

          Ок, теперь понятно, что рассуждать об алгоритмической сложности программ на JS можно только эмпирически.
          Ответить
          • Ну я бы балансировал тогда, когда это улучшает производительность. Но тут же возникает вопрос: а так ли нужна эта балансировка при том, что строки не изменяются и у нас есть информация о том, ссылается ли кто-то на под-дерево или нет. Может лучше просто склеить их при доступе по индексу?
            Ответить
            • > нужна эта балансировка при том, что строки не изменяются

              Балансировка нужна, чтобы быстро искать, неизменяемость тут не при чём.
              Если тупо приклеивать, получается колбаса вида
              .  join
                /    \
              a       join
                     /    \
                    b     ...
                             \
                              join
                             /    \
                            z      s
              Доступ по индексу будет медленным.

              > Может лучше просто склеить их при доступе по индексу?
              Наверное, можно, но тогда в каждый доступ по индексу приезжают нетривиальные ветвления. В целом оптимизаторы могут и такое выпилить, но уж как-то всё сложно и непредсказуемо получается.
              Ответить
          • JS - не тот язык, где нужно рассуждать - так нужно лепить замок из говна, быыыыыстро, блеать!
            Ответить
            • У тебя не должно времени писать на гк, замок рушится, обмажь еще говном.
              Ответить
        • Всмысле они как в паскеле и в MFC чтоли? Сначала хранится длина строки, и можно за одно сложение узнать ее конец?
          Ответить
          • Нет, смысл в том, что строки не являются массивами, а деревьями, где значения в узлах - массивы. Вставка в такое дерево может быть сделана за О(1) потому что можно просто взять вершину этого дерева и заменить ее на вставляемый узел, а потом назначить бывшую вершину веткой вставляемому узлу.
            У разных деревьев могут быть разные контракты относительно того, как соотносятся значения в узлах. Конкретно в ropes нужно поддерживать контракт, что количество дочерних узлов в правой ветке примерно равно количеству узлов в левой ветке.
            Вставка может нарушить контракт, но вот вопрос когда нужно заниматься исправлением: можно это делать при каждой вставке, а можно это делать при доступе к элементам.
            Ответить
      • Ну дык, "абсракция" же. Детали реализации, сложность, условия нормальной работы, гарантии знать не нужно. Работает, и ладно.
        Ответить
        • "Наш сайт точно откроется за время жизни Вселенной"
          Ответить
          • Какое-то ненадёжное обещание.

            Наш сайт точно откроется за время жизни Бога*
            * При условии существования Вселенной, планеты Земля, человечества на определённом этапе развития, ЭВМ определённой архитектуры, доступности энергии и ежедневных взносов пользователей в размере 0.05 МРОТ.
            Ответить
      • Там в реквестах уже есть реализация которая за логарифм пробелы собирает, ахаха.
        Ответить
  • Навскидку от человека, посвятившего изучению JavaScript целых 2 дня:
    str = Array(len+1).join(ch) + str; //так лучше?
    И вообще, как это лучше всего делается?
    Ответить
    • Думаю, тут надо подождать, пока все обновятся до актуальных версий и использовать String.prototype.repeat:
      function leftpad (str, len, ch) {
        if (!ch && ch !== 0) ch = ' ';
        len = Math.max(0, len - str.length);
        return String(ch).repeat(len) + String(str);
      }

      Иначе это - какие-то догадки и споры о внутреннем мире неразделанного медведя.

      > str = Array(len+1).join(ch) + str; //так лучше?
      Зависит от версии интерпретатора. Может, в какой-то эту операцию сильно соптимизировали.
      Ответить
      • >Думаю, тут надо подождать, пока все обновятся до актуальных версий
        Двоичный поискДвоичное склеивание рулит.

        Polyfill

        This method has been added to the ECMAScript 6 specification and may not be available in all JavaScript implementations yet. However, you can polyfill String.prototype.repeat() with the following snippet:

        if (!String.prototype.repeat) {
          String.prototype.repeat = function(count) {
            'use strict';
            if (this == null) {
              throw new TypeError('can\'t convert ' + this + ' to object');
            }
            var str = '' + this;
            count = +count;
            if (count != count) {
              count = 0;
            }
            if (count < 0) {
              throw new RangeError('repeat count must be non-negative');
            }
            if (count == Infinity) {
              throw new RangeError('repeat count must be less than infinity');
            }
            count = Math.floor(count);
            if (str.length == 0 || count == 0) {
              return '';
            }
            // Ensuring count is a 31-bit integer allows us to heavily optimize the
            // main part. But anyway, most current (August 2014) browsers can't handle
            // strings 1 << 28 chars or longer, so:
            if (str.length * count >= 1 << 28) {
              throw new RangeError('repeat count must not overflow maximum string size');
            }
            var rpt = '';
            for (;;) {
              if ((count & 1) == 1) {
                rpt += str;
              }
              count >>>= 1;
              if (count == 0) {
                break;
              }
              str += str;
            }
            // Could we try:
            // return Array(count + 1).join(this);
            return rpt;
          }
        }
        Ответить
    • Array(len+1).join(ch) + str случаем не вернет строку длинной 2 * (len + 1) - 1 + str.Length?
      Ответить
      • Хромоинтерпретатор:

        s=Array(6).join('.')
        > "....."
        s.length
        > 5

        Вроде, всё в порядке
        Ответить
  • Господи, оказывается эта история породила нехилый шитщторм.

    We should do that for each language we like to troll.

    A Java left pad implementing a Padder class instanciated by a PadderFactory that you can get by a PadderInjector from a PadderRegistry all that accepting an AbstractPaddingString.

    Then one in Ruby where you monkey patch the string that it pads, then add an AUTO_PAD settings set to True by default and a fluent API to chain padding.

    Then one version PHP version containing pad_string, then real_pad_string that deals with unicode, then real_pad_string_i_swear_this_time that that call str() on parameters automatically.

    Then a Haskell one with a monad and a trampolin and some |=> giberrish to mix it all.

    Then a Go one that creates a string padding microservice based on goroutine. With a docker file, just in case.

    And because we should never forget to be able to mock ourself, an aio_string_pad which gives you an asyncronous padding coroutine, but under the wood calling run_in_executor, and optionally auto start an event loop.
    Ответить
    • Посоны еще зделали облачный left-pad

      http://left-pad.io/

      8         d'b   o                           8     o
      8         8     8                           8
      8 .oPYo. o8P   o8P       .oPYo. .oPYo. .oPYo8    o8 .oPYo.
      8 8oooo8  8     8  ooooo 8    8 .oooo8 8    8     8 8    8
      8 8.      8     8        8    8 8    8 8    8     8 8    8
      8 `Yooo'  8     8        8YooP' `YooP8 `YooP' 88  8 `YooP'
      ..:.....::..::::..:::::::8 ....::.....::.....:..::..:.....:
      :::::::::::::::::::::::::8 ::::::::::::::::::::::::::::::::
      :::::::::::::::::::::::::..::::::::::::::::::::::::::::::::
      
      Welcome to left-pad.io!
      Ответить
      • ## History
        
        On March 22nd 2016, a terrible tragedy befell the Node.JS community. A popular
        microframework for robust string expansion, `left-pad`, was removed from
        npmjs.com.
        
        This resulted in broken deploys worldwide, a sudden and complete inability to
        appropriately zero-pad the fractional real cent value of many stock options,
        and untold billions of dollars in economic damage to the still nascent startup
        ecosystem of String Manipulation as a Service.
        
        ## A microservice saviour appears
        
        In order to prevent such a terrible tragedy from occurring ever again during
        our lifetimes, `left-pad.io` has been created to provide all the functionality
        of `left-pad` AND the overhead of a TLS handshake and an HTTP request.
        
        Less code is better code, leave the heavy lifting to `left-pad.io`, The String
        Experts™.
        
        ## How do I make use of left-pad.io?
        
        Simple! Just make a request to `https://api.left-pad.io`:
        
        ```
        $ curl 'https://api.left-pad.io/?str=paddin%27%20oswalt&len=68&ch=@&#039;
        {"str":"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@paddin' oswalt"}
        ```
        
        The query parameter names `str`, `len`, and `ch` match the argument names of
        our fallen comrade in left-stringist thought, `leftpad()`. May the Developer
        Happiness achieved forever commemorate its sacrifice.
        
        `left-pad.io` is 100% REST-compliant as defined by some guy on Hacker News with
        maximal opinions and minimal evidence.
        Ответить
          • в самом деле
            я думал, там какую-нибудь архитектурную уязвимость в протоколе IP нашли или что-то вроде этого, а они пишут про обосрамс каких-то тупых хиптеров
            Ответить
            • Кстати, веский аргумент в пользу того, чтобы не зависеть от дурацких репозиториев и CDN, а всё хранить у себя.

              И вообще облачные сервисы — это ловушка.
              Ответить
              • Спустя десять лет после заявления Столлмана стало понятно, что он был прав. Стабильность.
                Ответить
    • А в С модифицируют память до строки, забивая её пробелами и вычитают соответствующее число из указателя на начало строки?
      Ответить

Добавить комментарий

Помни, guest, за тобой могут следить!

    А не использовать ли нам bbcode?


    8