Javascript-форум (https://javascript.ru/forum/)
-   Ваши сайты и скрипты (https://javascript.ru/forum/project/)
-   -   разделение числа на разряды (https://javascript.ru/forum/project/35290-razdelenie-chisla-na-razryady.html)

Sober_exe 06.02.2013 16:30

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

$(document).ready(function(){$('*[separation]').separation();});

$.fn.separation = function(){ // separation - имя атрибута
    var target = this.text(); // берём строку
    var len = target.length; // получаем её длину
    var b = []; //создаём массив
    if(len > 3){ //проверяем, нужно ли обрабатывать строку
        var count = parseInt(len/3); // получаем количество троек (3 цифры)
        var start = len % 3; // берём первые цифры 
        var a = target.slice(0, start); // записываем их
        for(var i = 0; i<count; i++){ // пробегаемся по полученным тройкам
            if(i == 0){ //первая итерация
                b.push(target.slice(start, start+3)); //записываем в массив
                var index = start+3; // записываем индекс цифры, на которой остановились
            } else { // остальные итерации
                b.push(target.slice(index, index+3)); // аналагично записываем в массив
                index = index+3;
            };
        };
        this.html(a+' '+ b.join(' ')); //собираем всё и единожды обращаемся к DOM-дереву и записываем результат с разделителем
    }
}


Минусы:
1) громоздко
2) тег с рабочим атрибутом должен оборачивать только цифры (тег любой, но span предпочтительнее, т.к. не меняет визуальное отображение)
Плюсы:
1) можно указывать любой разделитель
2) Слышал мнение, что циклы быстрее регулярки (кстати, так ли это?)
3) написал сам, для развития хорошо (но это личный плюс)

В итоге, когда у нас есть строка <span separation>1000000</span>, на выходе мы получаем 1 000 000.

Вариант с регуляркой нашёл позже, вот он:

var str = 'Lorem ipsum 234456234 Lorem ipsum 7345287346 asdfae';
alert(str.replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 '));


Есть предложения по улучшению, замечания?

Островитянин 06.02.2013 16:33

пфффф ......, ну ты понял

Deff 06.02.2013 17:50

http://javascript.ru/forum/misc/2978...tml#post188051

Sober_exe 06.02.2013 18:15

Цитата:

Сообщение от Deff (Сообщение 232022)

Я привёл этот пример из ссылки, если вы не заметили

Deff 06.02.2013 18:31

Sober_exe,
Я дал на конкретный пост с нужным примером
var text = "Lorem ipsum 234456234 Lorem ipsum 7345287346 asdfae";
var re = /(?=\B(?:\d{3})+(?!\d))/g
alert( text.replace( re, ' ' ) );

Sober_exe 07.02.2013 13:06

Видоизменил на следующее:
$.fn.separation = function(){
    var target = this.text();
    this.attr('basicValue',target.match(/\d+/g)); //создаём атрибут специальный куда запишем начальное значение, для того что бы, можно было к нему обратится при необходимости
    var re = /(?=\B(?:\d{3})+(?!\d))/g;
    this.html(target.replace( re, ' ' ));
}


В итоге:
1. Оборачивать только цифры теперь не надо, буквы отсекаться будут
2. Ставим атрибут "separation" на общий тег
3. В этом теге создастся ещё один атрибут "basicValue", где будет лежать начальное значение, без разделения (только цифры). При необходимости от туда можно брать значение

рони 07.02.2013 14:09

Sober_exe,
так как это jquery необходим return иначе прервётся цепочка вызовов.

Sober_exe 07.02.2013 14:53

рони,
Спасибо, добавил return в конец. А можете пояснить эту необходимость, я не в курсе того, что цепочка прервёться

рони 07.02.2013 15:12

Sober_exe,
Вот хтмл код
<div class="container" >
 1234567890
 </div>
 <div class="container" >
 777777777
 </div>

вот код запуска
alert($('.container').separation().text());

попробуйте сделать код чтоб всё работало

Sober_exe 07.02.2013 16:04

рони, спасибо! я понял

Sober_exe 08.02.2013 12:35

столкнулся с проблемой.
Если на странице будет присутствовать не один такой атрибут то он в каждый записывал значение всех строк.
Решил сделать через .each(), но повалились другие ошибки, через консоль выяснил, что в this передаётся элемент дом дерева с набором свойств.
И в итоге рабочая версия такая:

$.fn.separation = function(){
    this.each(function(){
    var target = this.childNodes[0].nodeValue;
    this.setAttribute('basicValue', target.match(/\d+/g));
    var re = /(?=\B(?:\d{3})+(?!\d))/g;
    this.innerHTML = target.replace( re, '&#8201;' );
    return;
    });
}

рони 08.02.2013 12:49

Sober_exe,
Возможный вариант ...
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8" />
<script src="http://code.jquery.com/jquery-latest.js"></script>
  <title></title>
</head>
<body>
<div class="container" >
 1234567890
 </div>
 <div class="container" >
 777777777
 </div>
<script type="text/javascript">
$.fn.separation = function (options) {
    var o = jQuery.extend({
            separator: ' ', //разделитель по умолчанию
            recovery : false //востановить прежнее значение
                          }, options);
    return this.each(function (index, self) {
        var target = $(self).text();
        !$(self).data('recovery') && $(self).data('recovery', target); //создаём атрибут специальный куда запишем начальное значение, для того что бы, можно было к нему обратится при необходимости
        var re = /(?=\B(?:\d{3})+(?!\d+))/g;
        target = o.recovery ?  $(self).data('recovery') : $(self).data('recovery').replace(re, o.separator) ;
        $(self).html(target);
    })
}
alert($('.container').separation().text());//разделить на 3
alert($('.container').separation({separator:'__'}).text()); //разделить на 3 и-или поменять разделить
alert($('.container').separation({'recovery':true}).text());//востановить прежнее значение
</script>
</body>

Sober_exe 08.02.2013 14:01

круто!


Часовой пояс GMT +3, время: 09:33.