1. JavaScript / Говнокод #8236

    +164

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    function trim(s)
    {
        var i,j;
        for (i = 0; i < s.length && s.charAt(i) == " "; i++);
        for (j = s.length-1; j >= 0 && s.charAt(j) == " "; j--);
        if (i<=j)
            return s.substring(i, j+1);
        else
            return '';
    }

    Запостил: opzab, 19 Октября 2011

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

    • оформление кода - ужасное.
      Ответить
      • оформление как раз отличное, иначе бы я не заметил что в конце каждого цикла стоит ;

        Или JS игнорирует ; ?
        Ответить
    • И что здесь плохого?
      Ответить
      • Кстати, только понял после того, как сам написал - в худшем случае, т.е. когда будет строка только из пробельных элементов код из примера буде проверять ее дважды, справа налево и слева направо. Так что код заслуженно здесь.
        Ответить
        • for (i = 0; i < s.length && s.charAt(i) == " "; i++);
              for (j = s.length-1; j >= i && s.charAt(j) == " "; j--);
              return s.substring(i, j+1);


          Фиксед?
          Ответить
    • Говно в стандарте JS, не определили функцию trim?
      Ответить
    • не говно. можно было бы и регулярками, но ИМО они будут медленее JIT-нутого JS.

      а так одним substring'ом все аккуратно чикается.
      Ответить
      • Делать trim регэкспами - это стрельба из пушки по воробьям. По мне так в этом посте вполне вменяемая реализация. Хотя вообще, конечно, отсутствие встроенного trim - это недоработка.
        Ответить
      • Регулярки в JS - самое быстрое, что в нем есть, если в нем вообще есть что-то быстрое, т.как это обращение к нативным библиотекам. Они даже могут при определенных раскладах быть быстрее Java регулярок (смотря какие библиотеки / сколько текста / какие именно операции). V8 по тестам восновном обгоняет Java 7 server
        http://shootout.alioth.debian.org/u32/javascript.php
        .
        Ответить
    • function trim(s) {
      	var a = 0, b = s.length - 1, 
      		c = s[0], d = { " " : 1, "\t" : 1, "\r" : 1, "\n" : 1 };
      	while (c in d) c = s[++a];
      	c = s[b];
      	while ((c in d) && b >= a) c = s[--b];
      	return s.substring(a, b + 1);
      }

      Если задаться целью оптимизации без использования регулярных выражений. :)
      Ответить
      • >var a,b,c,d;
        отдельным постом нужно


        А насичот js-регулярок - эт вы хорошо сказали.
        Ответить
        • жабьи скриптеры учатся по обфусцированному коду :-)
          Ответить
        • Написано же "оптимизация". JavaScript "помнит" имена всех локальных переменных, (потому что помнит весь текст функции, как есть), так что на сколько-то наносекунд будет быстрее %) в очень редких случаях.
          Ответить
          • тогда почему так много пробелов и функция не в одну строку?
            и вообще for - короче чем while и удобней.
            Ответить
            • Где короче?
              while (c in d)
              for (;c in d;)

              Удобство - личное дело. Мне так удобно, вам - по другому. Я не спорю, но оптимизация подразумевает что удобством можно пожертвовать.
              Количество пробельных элементов не повлияет на работу, но скажется на быстроте работы парсера, так что вы правы.
              В моем предыдущем сообщении было два предложения, прочитайте второе предложение, тоже.
              Ответить
              • упущена такая возможность for как итерации и объявления переменных.
                for (i=0;s[++i] in d;);
                for (j=s.lenght-1;(c in d) && s[j] >= a);--j);
                например
                Ответить
                • >for (i=0;s[++i] in d;);
                  for (i=0;s[i] in d;++i);
                  >for (j=s.lenght-1;(c in d) && s[j] >= a);--j);
                  for (j=s.lenght-1;(s[j] in d) && j >= i);--j);
                  *sefl-fix*
                  Ответить
                  • && j >= i) лишнее.
                    Ответить
                    • http://govnokod.ru/8236#comment114889

                      >в худшем случае, т.е. когда будет строка только из пробельных элементов код из примера буде проверять ее дважды, справа налево и слева направо.
                      Ответить
                      • Тогда только ) лишнее. ;)

                        В зависимости от реализации может оказаться выгоднее сделать s=s.substring(i) перед вторым циклом и упростить условие.
                        Ответить
                • Синтаксис объявления переменной внутри for и снаружи - одинаковый. Нет разницы в длине :)
                  "Зачем с" - в смысле "зачем-с", или зачем нужна переменная "с"? 1. Иногда мне скучно. 2. Согласен, можно было и без.
                  Улучшеный вариант:
                  function trim(s) {
                  	var a = -1, b = s.length, 
                  		c = { " " : 1, "\t" : 1, "\r" : 1, "\n" : 1 };
                  	while (s[++a] in c);
                  	while ((s[--b] in c) && b >= a);
                  	return s.substring(a, b + 1);
                  }
                  %)

                  for-in тут ни при чем, у вас не получится через for-in просмотреть все символы строки.
                  Ответить
                  • в первом while забыл условие
                    && a<b, где b = s.length,

                    >for (c in d)
                    работает точно так же как и while(c in d)
                    Ответить
                    • А оно там не нужно, т.как когда a будет за пределами массива, то s[++a] in X вернет false и цикл закончится.

                      >for (c in d)
                      >работает точно так же как и while(c in d)

                      Нет, в первом случае in - ключевое слово (т.е. является частью конструкции for-in и не имеет самостоятельного смысла), во втором - in - оператор (обычная функция записанная в инфиксной нотации). В первом случае вы перечисляете все ключи хеша, во втором вы проверяете наличие ключа в хеше. Т.е. в первом случае будет использоваться опкод next_value (для последовательного получения всех ключей в d), а во втором - get_property (для проверки наличия у d ключа c), ну или как-то так. Вобщем, эти операции даже не связаны между собой.
                      Ответить
                      • >Вобщем, эти операции даже не связаны между собой.
                        Ты прав.

                        Но проверку я бы оставил.
                        Ответить
              • тут
                for (c in d)
                Ответить
          • универсальная отмазка, ага
            Ответить
      • Зачем c?
        Ответить
    • А как реализован класс String?

      А то, помнится мне, в Java метод String.substring(...) вернет по сути ту же самую строку, которая была изначально, но приватные члены-данные нового объекта: offset, count изменятся, а value (массив символо) не изменится. Если ничего не путаю.
      Ответить
      • Блин. Точно. А я не знал.
        return ((beginIndex == 0) && (endIndex == count)) ? this :
        new String(offset + beginIndex, endIndex - beginIndex, value);

        // Package private constructor which shares value array for speed.
        String(int offset, int count, char value[]) {
        this.value = value;
        this.offset = offset;
        this.count = count;
        }
        Ответить
        • То есть, если я запишу
          String a="123",b;
          b = a.substring(0,3);
          b.concat("456");
          то
          System.out.println(a);
          Выведет в консольке - 123456
          Ответить
          • Никак нет, сер. Не выведет
            Оно по идее выведет стектрейс с ошибкой.
            >(0,3);
            Строки в жабе иммутабельны. + массивы что в них не умеют менять размер.
            При concate создастcя новый массив, скопирует туды оба значения и вернет новый стринг и с новым внутренним массивом.
            Ответить
            • Простите, не доглядел. Ведь метод concat не изменит внутреннего состояния объекта, который его вызывает, а вернет новый. И вообще все методы, которые логически должны менять массив символов строки.
              Ответить
      • В Javascript нет классов - только объекты и примитивы (сорри - просто ухо режет :) )
        Ответить
        • Буду знать.
          Студентота. А JavaScript только в следующем семестре.
          Но все таки. Где посмотреть можно?
          Ответить
          • В любой хорошей (думаю, в плохих могут сказать обратное) книге должно быть написано, что в Javascript есть только объекты и примитивы, а функции являются объектами первого порядка (first-class objects), т.е. любая функция является является инстансом Object
            > alert.constructor
            function Function() { [native code] }
            > Function instanceof Object
            true
            > alert instanceof Object
            true


            По части книг я бы порекомендовал Eloquent Javascript (Marijn Haverbeke), JavaScript: The Good Parts (Douglas Crockford), Javascript Patterns (Stoyan Stefanov). Ну потом можно, в принципе, прочитать еще Hight Performance Javascript. Сам очень советую Javascript Patterns, но она больше для "продвинутых" нежели Eloquent JS и JS The Good Parts.

            P.S. Протаете всё, на след. курсе на лекции по JS можно будет не ходить ;-)
            Ответить
    • показать все, что скрыторегулярки видимо для лохов
      Ответить

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