Пример склонения слов в javascript

Пример склонения слов в javascript
Комментарии: 18

Для склонения числовых значений будем использовать небольшую javascript функцию. В качестве аргументов ей передаётся число и массив из форм слова. Рассмотрим 2 варианта написания такой функции.

function declOfNum(number, words) {  
    return words[(number % 100 > 4 && number % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(number % 10 < 5) ? Math.abs(number) % 10 : 5]];
}

тоже самое, но другим синтаксисом:

function declOfNum(n, text_forms) {  
    n = Math.abs(n) % 100; 
    var n1 = n % 10;
    if (n > 10 && n < 20) { return text_forms[2]; }
    if (n1 > 1 && n1 < 5) { return text_forms[1]; }
    if (n1 == 1) { return text_forms[0]; }
    return text_forms[2];
}

Пример:

declOfNum(1, ['минута', 'минуты', 'минут']); // вернёт — минута
declOfNum(2, ['минута', 'минуты', 'минут']); // вернёт — минуты
declOfNum(5, ['минута', 'минуты', 'минут']); // вернёт — минут

На практике можно применять следующим образом:

document.getElementById('p1').innerHTML = '1 ' + declOfNum(1, ['минута', 'минуты', 'минут']);

// или на jQuery
$('#p2').html('2 '+declOfNum(2, ['минута', 'минуты', 'минут']));
$('#p3').html('5 '+declOfNum(5, ['минута', 'минуты', 'минут']));

Результат:

Вариант использования, когда значение вводится пользователем в текстовое поле. Для удобства используем jQuery.

// html
<input id="num" type="number" value="1" min="0" max="100" step="1" /> 
<span id="num-word">год</span>

// script
$('#num').on('change',function(){
    val = declOfNum($(this).val(), ['год', 'года', 'лет']);
    $('#num-word').text(val);
});

Результат: год

Так, изменяя падежи слова, можно составлять грамматически верные предложения с использованием числительных переменных.

Темы:
JavaScript
Ещё интересное — 6
Комментарии —
  1. Мишка
    Мишка24 февраля 2019, 21:01#
    Андрей, здравствуй. Помоги пожалуйста с построением кода. Как будет выглядеть готовый код для вставки? К примеру вариант с минутами...))
    1. Andy Si24 февраля 2019, 22:14#
      Добрый вечер. Так в статье есть пример, меняется только селектор, куда вставляется слово — у каждого он свой.
      1. Мишка
        Мишка25 февраля 2019, 16:18#
        Вставил в таком порядке, но отображения нету :((

        Мне кажется я допустил ошибку…

        <script>
        $('#num').on('change',function(){
                val = num2str($(this).val(), ['год', 'года', 'лет']);
                $('#num-word').text(val);
            });
        
        function num2str(n, text_forms) {  
                n = Math.abs(n) % 100; var n1 = n % 10;
                if (n > 10 && n < 20) { return text_forms[2]; }
                if (n1 > 1 && n1 < 5) { return text_forms[1]; }
                if (n1 == 1) { return text_forms[0]; }
                return text_forms[2];
            }
        </script>
        
        
        1. Andy Si25 февраля 2019, 16:25#
          Убедись, что у тебя на сайте подключена библиотека jquery. И код попробуй поменять на этот:
          <script>
          $(function(){
          	function num2str(n, text_forms) {  
                  n = Math.abs(n) % 100; var n1 = n % 10;
                  if (n > 10 && n < 20) { return text_forms[2]; }
                  if (n1 > 1 && n1 < 5) { return text_forms[1]; }
                  if (n1 == 1) { return text_forms[0]; }
                  return text_forms[2];
              }
          
          	$('#num').on('change',function(){
                  val = num2str($(this).val(), ['год', 'года', 'лет']);
                  $('#num-word').text(val);
              });	
          });
          </script>
          jQuery можно подключить так:
          <script src="https://code.jquery.com/jquery-git.min.js"></script>
    2. Кирилл
      Кирилл25 августа 2019, 19:52#
      if (n > 10 && n < 20) { return text_forms[2]; }
      от этого нет смысла, т.к. есть return text_forms[2];
      1. Andy Si26 августа 2019, 08:44(был изменён)#
        Не совсем так. Если этого условия не будет, то может сработать 2е или 3е условие с переменной n1, а до return text_forms[2]; дело не дойдет и мы получим неправильное значение.
      2. Mark
        Mark17 июня 2020, 20:24#
        Спасибо. Отлично работает!
        1. Таисия
          Таисия29 октября 2020, 16:43#
          Супееер, спасибо большое, прекрасно работает!!!
          1. Rrp
            Rrp15 декабря 2020, 18:45#
            Отлично! Спасибо
            1. Стас
              Стас08 января 2021, 11:13#
              Спасибо, работает :)
              А то самому писать формулу это такое.
              1. Andy Si09 января 2021, 18:35#
                Согласен :)
              2. Макс
                Макс22 июня 2021, 18:34#
                Большое спасибо за код.
                Есть небольшая поправка, в сокращенном виде не хватает Math.abs

                words[(number % 100 > 4 && number % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][(number % 10 < 5) ? Math.abs(number) % 10 : 5]]
                1. Andy Si23 июня 2021, 15:31#
                  Точно, если учитывать отрицательные числа, то не хватает. Добавил.
                2. Алексей
                  Алексей14 сентября 2021, 00:56#
                  Привет. Подскажи, допустим массив «секунда, секунды, секунд» и этот код.
                  Получается для 55 выполнится секунд — этот кусок кода (number % 100 > 4 && number % 100 < 20)? 2. То есть будет выбран «секунд» в массиве, но я не пойму, почему 55 дает остаток больше 4 и меньше 20. Помоги разобраться.
                  55/100 = 0.55 (Остаток 55? хм не пойму)
                  1. Andy Si14 сентября 2021, 08:56#
                    Привет… Ты всё правильно заметил, только при 55 условие
                    (number % 100 > 4 && number % 100 < 20)
                    вернёт false и программа перейдёт к куску кода
                    [2, 0, 1, 1, 1, 2][(number % 10 < 5) ? Math.abs(number) % 10 : 5]
                    А здесь уже number % 10 < 5 вернёт также false и соответственно получим [2, 0, 1, 1, 1, 2][5], а 5й элемент этого массива также равен 2.
                    1. Алексей
                      Алексей14 сентября 2021, 11:38#
                      О, разобрался, спасибо!
                  2. Алексей
                    Алексей10 мая 2022, 09:49#
                    ну а как быть, к примеру, с 11 минута и 111 минута?)
                    1. Andy Si10 мая 2022, 10:25#
                      Сейчас не могу проверить, но должно быть всё корректно. На сайте в примере 11 лет и 111 лет, значит и минутами всё должно работать.
                    © REALADMIN.RU   2024 г.
                    Страница сгенерирована: 0,0852 s | 4 mb.
                    На каком уровне Вы играете в шахматы?
                    OPROS