Правильная форма существительного рядом с числом (счетная форма)

Правильная форма существительного рядом с числом (счетная форма): 99 франков, 1000 и 1 ночь, 33 коровы

Правильная форма существительного рядом с числом (счетная форма): 99 франков, 1000 и 1 ночь, 33 коровы

Часто бывает нужно рядом с числом (числительным) написать существительное в правильной форме. Например, 99 франков, 1000 и 1 ночь, но 33 коровы.

Для этого есть специальная функция, которая в качестве параметров принимает число и три возможные варианта написания, например:

  1. «рубль» — для единственного числа именительного падежа
  2. «рубля» — для единственного числа родительного падежа
  3. «рублей» — для множественного числа родительного падежа

Реализация на Java Script

/*
 * Правильная форма cуществительного рядом с числом (счетная форма).
 *
 * @param integer _number Число
 * @param string _case1 Единственное число именительный падеж
 * @param string _case2 Единственное число родительный падеж
 * @param string _case3 Множественное число родительный падеж
 * @return string
 */
function getCase(_number, _case1, _case2, _case3)
{
    var base = _number - Math.floor(_number / 100) * 100;
    var result;

    if (base > 9 && base < 20) {
        result = _case3;

    } else {
        var remainder = _number - Math.floor(_number / 10) * 10;

        if (1 == remainder) result = _case1;
        else if (0 < remainder && 5 > remainder) result = _case2;
        else result = _case3;
    }

    return result;
}
Вызов, чтоб попробовать
var tryNumbers = new Array(51, 52, 55);

for (var i = 0; i < tryNumbers.length; i++) {
    alert(tryNumbers[i] + " " + getCase(tryNumbers[i], "рубль", "рубля", "рублей"));
}

Реализация на PHP

/**
 * Правильная форма cуществительного рядом с числом (счетная форма).
 *
 * @param integer _number Число
 * @param string _case1 Единственное число именительный падеж
 * @param string _case2 Единственное число родительный падеж
 * @param string _case3 Множественное число родительный падеж
 * @return string
 */
function getCase($_number, $_case1, $_case2, $_case3)
{
    $base = $_number - floor($_number / 100) * 100;
    $result = null;

    if ($base > 9 && $base < 20) {
        $result = $_case3;

    } else {
        $remainder = $_number - floor($_number / 10) * 10;

        if (1 == $remainder) $result = $_case1;
        else if (0 < $remainder && 5 > $remainder) $result = $_case2;
        else $result = $_case3;
    }

    return $result;
}
Вызов, чтоб попробовать
foreach (array(51, 52, 55) as $number) {
    echo $number, ' ' , getCase($number, 'рубль', 'рубля', 'рублей') . PHP_EOL;
}

Реализация на XSL(T)

<!--
Правильная форма cуществительного
рядом с числом (счетная форма).
-->
<xsl:template name="get-case">
    <xsl:param name="number"/> <!-- Число -->
    <xsl:param name="case1" /> <!-- Единственное число именительный падеж -->
    <xsl:param name="case2" /> <!-- Единственное число родительный падеж -->
    <xsl:param name="case3" /> <!-- Множественное число родительный падеж -->

    <xsl:variable name="base"
                  select="$number - floor($number div 100) * 100" />

    <xsl:choose>
        <xsl:when test="$base > 9 and $base &lt; 20">
            <xsl:value-of select="$case3" />
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="remainder"
                          select="$number - floor($number div 10) * 10" />
            <xsl:choose>
                <xsl:when test="$remainder = 1">
                    <xsl:value-of select="$case2" />
                </xsl:when>
                <xsl:when test="$remainder > 0 and $remainder &lt; 5">
                    <xsl:value-of select="$case2" />
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$case3" />
                </xsl:otherwise>
            </xsl:choose>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
Вызов, чтоб попробовать
<xsl:text>51 </xsl:text>
<xsl:call-template name="get-case">
    <xsl:with-param name="number" select="51" />
    <xsl:with-param name="case1">рубль</xsl:with-param>
    <xsl:with-param name="case2">рубля</xsl:with-param>
    <xsl:with-param name="case3">рублей</xsl:with-param>
</xsl:call-template>

<xsl:text>52 </xsl:text>
<xsl:call-template name="get-case">
    <xsl:with-param name="number" select="52" />
    <xsl:with-param name="case1">рубль</xsl:with-param>
    <xsl:with-param name="case2">рубля</xsl:with-param>
    <xsl:with-param name="case3">рублей</xsl:with-param>
</xsl:call-template>

<xsl:text>55 </xsl:text>
<xsl:call-template name="get-case">
    <xsl:with-param name="number" select="55" />
    <xsl:with-param name="case1">рубль</xsl:with-param>
    <xsl:with-param name="case2">рубля</xsl:with-param>
    <xsl:with-param name="case3">рублей</xsl:with-param>
</xsl:call-template>