Правильные числительные
![](http://studioad.ru/_bl/0/09401476.jpg)
Я нашел достаточно простой и быстрый способ решения этой проблемы. Мой скрипт поможет правильно расставить существительные в правильной форме и ваши записи превратятся в 100 комментариев и 3 ответа. Скрипт работает во всех браузерах. Пример использования скрипта можно посмотреть в моем блоге.
Для установки скрипта, скажем, в ваш блог, поместите число комментариев в span* с соответствующим классом**. Пример:
Code
<!-- Было -->
Комментарии:<b>$COMMENTS_NUM$</b>
<!-- Стало -->
<b><span class='comms'>$COMMENTS_NUM$</span></b>
Комментарии:<b>$COMMENTS_NUM$</b>
<!-- Стало -->
<b><span class='comms'>$COMMENTS_NUM$</span></b>
Затем в конец страницы вставьте скрипт:
Code
<script type="text/javascript">
setNum = function(c,n){
var a,b,i,d;
a = document.all||document.getElementsByTagName('*');
for(b=0;b<a.length;b++){if(new RegExp("(^|\\b)"+c+"(\\b|$)").test(a[b].className)){
i = function(){
d = parseFloat(a[b].innerHTML);
if(!d){return n[2]}else
if(d%1){return n[1]}else
if(/(11|12|13|14|5|6|7|8|9|0)$/.test(d)){return n[2]}else
if(/1$/.test(d)){return n[0]}else
if(/(2|3|4)$/.test(d)){return n[1]}
};
a[b].innerHTML=i().replace(/\{N\}/,d||0);
}}
}
</script>
setNum = function(c,n){
var a,b,i,d;
a = document.all||document.getElementsByTagName('*');
for(b=0;b<a.length;b++){if(new RegExp("(^|\\b)"+c+"(\\b|$)").test(a[b].className)){
i = function(){
d = parseFloat(a[b].innerHTML);
if(!d){return n[2]}else
if(d%1){return n[1]}else
if(/(11|12|13|14|5|6|7|8|9|0)$/.test(d)){return n[2]}else
if(/1$/.test(d)){return n[0]}else
if(/(2|3|4)$/.test(d)){return n[1]}
};
a[b].innerHTML=i().replace(/\{N\}/,d||0);
}}
}
</script>
Code
<script type="text/javascript">
// в квадратных скобках нужное существительное в 3 разных видах
// в именительном, родительном, и родительном в множественном числе
// в каждой строчке {N} заменяется на число
// не перепутайте последовательность!
setNum('comms',['<b>{N}</b> комментарий','<b>{N}</b> комментария','<b>{N}</b> комментариев']);
</script>
// в квадратных скобках нужное существительное в 3 разных видах
// в именительном, родительном, и родительном в множественном числе
// в каждой строчке {N} заменяется на число
// не перепутайте последовательность!
setNum('comms',['<b>{N}</b> комментарий','<b>{N}</b> комментария','<b>{N}</b> комментариев']);
</script>
* не обязательно span, можно и любой другой элемент.
** класс должен быть один для каждой отдельной группы. Например для комментариев - comms.
ВИДЕОДЕСЕРТ
Сегодня на десерт один из мультиков серии про животных Саймона и их приключения. Мне искренне нравятся эти короткие анимационные зарисовки. Надеюсь, понравятся и вам.:
32, 14, 6560
Что-то еще что ли нужно сделать?
Как Вы профилировали не знаю, но http://helper.ucoz.ru/scripts-porfiling.html в 90% случаев демонструет ожидаемое превосходство арифметических действий над разбором строки регулярными выражениями.
Моя функция:
function i(d,n){d=d||0;if(!d){return d+n[2]}else if(d%1){return d+n[1]}else if(/(11|12|13|14|5|6|7|8|9|0)$/.test(d)){return d+n[2]}else if(/1$/.test(d)){return d+n[0]}else if(/(2|3|4)$/.test(d)){return d+n[1]}};
Присланная функция:
function format(g,d){if(typeof d.onlyroot=="undefined"){d.onlyroot=false}var c=parseInt((g%100)/10),e=g%10,f=(d.onlyroot?"":g+" ")+d.root;switch(e){case 0:case 5:case 6:case 7:case 8:case 9:f+=d.end[2];break;case 1:f+=c==1?d.end[2]:d.end[0];break;case 2:case 3:case 4:f+=c==1?d.end[2]:d.end[1];break}return f};
Тест скорости в миллисекундах:
Для 1000 элементов
FireFox format: 92ms, i: 89ms
Opera 10 format: 68ms, i: 71ms
Chrome format: 45ms, i: 46ms
Safari format: 45ms, i: 40ms
IE8 format: 566ms, i: 551ms
Для 10000 элементов
FireFox format: 4469ms, i: 4492ms
Opera 10 format: 15335ms, i: 13940ms
Chrome format: 3162ms, i: 2983ms
Safari format: 2278ms, i: 2304ms
IE8 format: 49926ms, i: 49490ms
Итоги: мнение о том, что регекспы работают медленнее - не оправдались. Обе функции в одних браузерах лидируют, в других проигрывают, но во всех случаях разница в скорости выполнения неощутимо мала.
Но мой вариант функции короче и лидирует в большем числе тестов.
function format(n,a){if(typeof a.onlyroot=='undefined')a.onlyroot=false;var b=parseInt((n%100)/10),_u=n%10,_r=(a.onlyroot?'':n+' ')+a.root;switch(_u){case 0:case 5:case 6:case 7:case 8:case 9:_r+=a.end[2];break;case 1:_r+=b==1?a.end[2]:a.end[0];break;case 2:case 3:case 4:_r+=b==1?a.end[2]:a.end[1];break};return _r}
Вызывать как format(колво_записей, {root:'корень',['окончание для одного','для двух, трех, четырех','для пяти и более']})
не format(колво_записей, {root:'корень',['окончание для одного','для двух, трех, четырех','для пяти и более']})
а format(колво_записей, {root:'корень',end:['окончание для одного','для двух, трех, четырех','для пяти и более']})
И кстати да, ваша кривая функция не работает с дробями. А моя это предусматривает.
Комментариев: 666, голосов: 333