Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Смена окончания при подсчёте (https://javascript.ru/forum/misc/36941-smena-okonchaniya-pri-podschjote.html)

qwermjk 01.04.2013 20:41

Смена окончания при подсчёте
 
Может кому нибудь из читающих форум, будет интересен скриптик!!
При подсчёте чегонибудь, допустим, яблок ... мы меняем окончание когда произносим: 1 яблоко, 2 яблока, 5 яблок ...
function wordend(number, word, end1, end2, end3){
	if(Number(String(number).length) > 2) number = Number(String(number).substr(-2));
	if(number == 11 || number == 12 || number == 13 || number == 14){
		return word+end3;
	} else {
		switch(Number(String(number).substr(-1))){
			case 1: return word+end1; break;
			case 2:case 3:case 4: return word+end2; break;
			case 5:case 6:case 7:case 8:case 9:case 0: return word+end3; break;
		}
	}
}

alert(111+' '+wordend(111, 'став', 'ка', 'ки', 'ок'));
alert(1+' '+wordend(1, 'яблок', 'о', 'а', ''));
alert(5+' '+wordend(5, 'секунд', 'а', 'ы', ''));

dmitriymar 01.04.2013 20:46

Цитата:

Сообщение от qwermjk
Может кому нибудь из читающих форум, будет интересен скриптик!!
При подсчёте чегонибудь, допустим, яблок ... мы меняем окончание когда произносим: 1 яблоко, 2 яблока, 5 яблок ...

а со стульями то не работает:-E

qwermjk 01.04.2013 21:01

Цитата:

Сообщение от dmitriymar
а со стульями то не работает

alert(1+' '+wordend(1, 'стул', '', 'а', 'ьев'));

Меняем везде цифру 1, на любое другое число! И всё работать будет ... Просто надо правильно корень слова взять ...
в функции wordend, первый параметр, это количество (времени, предметов и тд), второй параметр - неизменная часть слова, которая будет во всех трёх случаев ... 1 СТУЛ, 2 СТУЛа, 5 СТУЛьев - а из этого вы уже догодались откуда берутся 3,4,5 параметры ...

nikita.mmf 02.04.2013 00:25

function pluralForm ( n, forms ) {
    return forms[(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2) ];
}
//pluralForm( 1, ["стул", "стула", "стульев"] );

Aetae 02.04.2013 01:40

У каждого свой костыль:)
function num(n, one, two, five) {
    if ((n = Math.abs(n) % 100) > 4 && n < 21 || (n %= 10) > 4 || n === 0 ) return five;
    if (n > 1) return two;
    return one;
}

qwermjk 02.04.2013 10:21

Мда!! оказывается у меня самый тупой метод =)) Ладно, переделаем ...

qwermjk 02.04.2013 10:43

Вот, вторая попытка!!!
function wordend(num, words){
	return words[((num%100 > 10 && num%100 < 15) || num%10 > 4 || num%10 == 0)? 2 : (num%10 == 1)? 0 : 1];	
}

alert(11+' '+wordend(11, ['стул','стула','стульев']));

Aetae 02.04.2013 13:56

qwermjk, очевидная оптимизация:
function wordend(num, words){
    return words[ ((num=Math.abs(num%100)) > 10 && num < 15 || (num%=10) > 4 || num === 0) ? 2 : num === 1 ? 0 : 1 ];
}
Но тут ещё есть куда оптимизировать(напр. последний пункт).)

P.S. Math.abs - модуль - нужен чтобы работало и с отрецательными числами.

qwermjk 02.04.2013 14:47

Цитата:

Сообщение от Aetae
P.S. Math.abs - модуль - нужен чтобы работало и с отрецательными числами.

По идеи он вообще не нужен!!! просто в функцию загоняем положительное число, а где вывести нужно, там отрицательное!!
Так как с отрицательными числами врядли будет использоваться эта функция!! например так:
alert(-11+' '+wordend(11, ['стул','стула','стульев']));

Aetae 03.04.2013 09:58

Хехех, по идее - наоборот первой проверкой должна стоять проверка "а число ли нам вообще передают", далее должна идти проверка не дробное ли...)

Aetae 12.04.2013 01:28

function wordend(num, words){
    return words[ ((num=Math.abs(num%100)) > 10 && num < 15 || (num%=10) > 4 || num === 0) + (num !== 1) ];
}
alert(11+' '+wordend(11, ['стул','стула','стульев']));

Ещё чуток сократил, хотя это, конечно, просто баловство.)

qwerty-клавиатура 12.04.2013 17:51

http://x9a.ru/склонение-слов-и-количество/

Aetae 12.04.2013 19:13

qwerty-клавиатура, да, что-то в этом есть:
function wordend(num, words){
    if((num=Math.abs(num%100)) > 20) num%=10;
    return words[ (num > 4 || num === 0) + (num !== 1) ];
}

можно дальше развлекаться))

qwerty-клавиатура 12.04.2013 19:34

зачем abs? хотя -1 градус, -2 градусов. Не все таки оно не нужно

qwerty-клавиатура 12.04.2013 21:13

это плохая функция во-первых у слов месть одинаковая основа, меняются только окончания, а во-вторых я тоже умею однострочники писать

function pluralize(count, base, singular, plural1, plural2) { 
    return count + ' ' + base + ( ( count = (count %= 100) > 20 ? count % 10 : count ) == 0 || count > 4 ? plural2 : count > 1 ? plural1 : singular ); 
}

qwerty-клавиатура 12.04.2013 21:13

for (var i = 0; i < 1000; ++i) console.log( pluralize(i, 'бутыл', 'ка', 'ки', 'ок') )

Aetae 12.04.2013 21:38

Если уж так хочется писать не целые слова, а куски, пожалуйсто:
num + 'бутыл' + wordend(num, ['ка', 'ки', 'ок'])

При этом в отличие от того, что предлагаете, вы между цифрой и текстом может быть любой разделитель, а не только пробел.

Но это мелочи, интересно другое:
1. Чем плохая? (по сути они одинаковы же)
2. Интерес не в длинном однострочнике, а в максимальном сокращении лишних телодвижений.)

Цитата:

Сообщение от qwerty-клавиатура (Сообщение 245841)
зачем abs? хотя -1 градус, -2 градусов. Не все таки оно не нужно

function wordend(num, words){
    if((num=Math.abs(num%100)) > 20) num%=10;
    return words[ (num > 4 || num === 0) + (num !== 1) ];
}
function pluralize(count, base, singular, plural1, plural2) {
    base = count + ' ' + base;
    count = (count %= 100) > 20 ? count % 10 : count;
    return base + (count == 0 || count > 4 ? plural2 : count > 1 ? plural1 : singular);
}

alert([
    'wordend: -2 градус' + wordend(-2, ['', 'a', 'ов']),
    '\npluralize: ' + pluralize(-2, 'градус', '', 'а', 'ов')
]);

И почему же не нужно? Сейчас не нужно, а потом получив глюк отвлекаться от работы и вспоминать, что в функции нет проверки на знак?

qwerty-клавиатура 12.04.2013 23:05

ну -1, -2, -3 это применимо только к температуре, всем понятна такая запись -2°C, количество не может быть отрицательным(труп либо есть, либо его нет). Пример таймера использовать http://x9a.ru/samples/timer.htm


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