1 PluralRules Objects

1.1 The Intl.PluralRules Constructor

The PluralRules constructor is the %PluralRules% intrinsic object and a standard built-in property of the Intl object. Behaviour common to all service constructor properties of the Intl object is specified in .

1.1.1 Intl.PluralRules ( [ locales [ , options ] ] )

When the Intl.PluralRules function is called with optional arguments locales and options, the following steps are taken:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let pluralRules be ? OrdinaryCreateFromConstructor(NewTarget, "%PluralRules.prototype%", « [[InitializedPluralRules]], [[Locale]], [[Type]], [[MinimumIntegerDigits]], [[MinimumFractionDigits]], [[MaximumFractionDigits]], [[MinimumSignificantDigits]], [[MaximumSignificantDigits]], [[RoundingType]], [[RoundingMode]], [[RoundingIncrement]], [[TrailingZeroDisplay]] »).
  3. Return ? InitializePluralRules(pluralRules, locales, options).

1.1.2 InitializePluralRules ( pluralRules, locales, options )

The abstract operation InitializePluralRules accepts the arguments pluralRules (which must be an object), locales, and options. It initializes pluralRules as a PluralRules object. The following steps are taken:

  1. Let requestedLocales be ? CanonicalizeLocaleList(locales).
  2. Set options to ? CoerceOptionsToObject(options).
  3. Let opt be a new Record.
  4. Let matcher be ? GetOption(options, "localeMatcher", string, « "lookup", "best fit" », "best fit").
  5. Set opt.[[localeMatcher]] to matcher.
  6. Let t be ? GetOption(options, "type", string, « "cardinal", "ordinal" », "cardinal").
  7. Set pluralRules.[[Type]] to t.
  8. Perform ? SetNumberFormatDigitOptions(pluralRules, options, +0𝔽, 3𝔽, "standard").
  9. Let localeData be %PluralRules%.[[LocaleData]].
  10. Let r be ResolveLocale(%PluralRules%.[[AvailableLocales]], requestedLocales, opt, %PluralRules%.[[RelevantExtensionKeys]], localeData).
  11. Set pluralRules.[[Locale]] to r.[[locale]].
  12. Return pluralRules.

1.2 Properties of the Intl.PluralRules Constructor

The Intl.PluralRules constructor has the following properties:

1.2.1 Intl.PluralRules.prototype

The value of Intl.PluralRules.prototype is %PluralRules.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

1.2.2 Intl.PluralRules.supportedLocalesOf ( locales [ , options ] )

When the supportedLocalesOf method is called with arguments locales and options, the following steps are taken:

  1. Let availableLocales be %PluralRules%.[[AvailableLocales]].
  2. Let requestedLocales be ? CanonicalizeLocaleList(locales).
  3. Return ? SupportedLocales(availableLocales, requestedLocales, options).

1.2.3 Internal slots

The value of the [[AvailableLocales]] internal slot is implementation-defined within the constraints described in .

The value of the [[RelevantExtensionKeys]] internal slot is « ».

Note 1
Unicode Technical Standard #35 describes no locale extension keys that are relevant to the pluralization process.

The value of the [[LocaleData]] internal slot is implementation-defined within the constraints described in .

Note 2
It is recommended that implementations use the locale data provided by the Common Locale Data Repository (available at https://cldr.unicode.org/).

1.3 Properties of the Intl.PluralRules Prototype Object

The Intl.PluralRules prototype object is itself an ordinary object. %PluralRules.prototype% is not an Intl.PluralRules instance and does not have an [[InitializedPluralRules]] internal slot or any of the other internal slots of Intl.PluralRules instance objects.

1.3.1 Intl.PluralRules.prototype.constructor

The initial value of Intl.PluralRules.prototype.constructor is %PluralRules%.

1.3.2 Intl.PluralRules.prototype [ @@toStringTag ]

The initial value of the @@toStringTag property is the String value "Intl.PluralRules".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

1.3.3 Intl.PluralRules.prototype.select ( value )

When the select method is called with an argument value, the following steps are taken:

  1. Let pr be the this value.
  2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
  3. Let n be ? ToNumber(value).
  4. Return ! ResolvePlural(pr, n).[[PluralCategory]].

1.3.4 Intl.PluralRules.prototype.selectRange ( start, end )

When the selectRange method is called with arguments start and end, the following steps are taken:

  1. Let pr be the this value.
  2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
  3. If start is undefined or end is undefined, throw a TypeError exception.
  4. Let x be ? ToNumber(start).
  5. Let y be ? ToNumber(end).
  6. Return ? ResolvePluralRange(pr, x, y).

1.3.5 Intl.PluralRules.prototype.resolvedOptions ( )

This function provides access to the locale and options computed during initialization of the object.

  1. Let pr be the this value.
  2. Perform ? RequireInternalSlot(pr, [[InitializedPluralRules]]).
  3. Let options be OrdinaryObjectCreate(%Object.prototype%).
  4. For each row of Table 1, except the header row, in table order, do
    1. Let p be the Property value of the current row.
    2. Let v be the value of pr's internal slot whose name is the Internal Slot value of the current row.
    3. If v is not undefined, then
      1. Perform ! CreateDataPropertyOrThrow(options, p, v).
  5. Let pluralCategories be a List of Strings containing all possible results of PluralRuleSelect for the selected locale pr.[[Locale]].
  6. Perform ! CreateDataProperty(options, "pluralCategories", CreateArrayFromList(pluralCategories)).
  7. If pr.[[RoundingType]] is morePrecision, then
    1. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "morePrecision").
  8. Else if pr.[[RoundingType]] is lessPrecision, then
    1. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "lessPrecision").
  9. Else,
    1. Perform ! CreateDataPropertyOrThrow(options, "roundingPriority", "auto").
  10. Return options.
Table 1: Resolved Options of PluralRules Instances
Internal Slot Property
[[Locale]] "locale"
[[Type]] "type"
[[MinimumIntegerDigits]] "minimumIntegerDigits"
[[MinimumFractionDigits]] "minimumFractionDigits"
[[MaximumFractionDigits]] "maximumFractionDigits"
[[MinimumSignificantDigits]] "minimumSignificantDigits"
[[MaximumSignificantDigits]] "maximumSignificantDigits"
[[RoundingMode]] "roundingMode"
[[RoundingIncrement]] "roundingIncrement"
[[TrailingZeroDisplay]] "trailingZeroDisplay"

1.4 Properties of Intl.PluralRules Instances

Intl.PluralRules instances are ordinary objects that inherit properties from %PluralRules.prototype%.

Intl.PluralRules instances have an [[InitializedPluralRules]] internal slot.

Intl.PluralRules instances also have several internal slots that are computed by the constructor:

  • [[Locale]] is a String value with the language tag of the locale whose localization is used by the plural rules.
  • [[Type]] is one of the String values "cardinal" or "ordinal", identifying the plural rules used.
  • [[MinimumIntegerDigits]] is a non-negative integer Number value indicating the minimum integer digits to be used.
  • [[MinimumFractionDigits]] and [[MaximumFractionDigits]] are non-negative integer Number values indicating the minimum and maximum fraction digits to be used. Numbers will be rounded or padded with trailing zeroes if necessary.
  • [[MinimumSignificantDigits]] and [[MaximumSignificantDigits]] are positive integer Number values indicating the minimum and maximum fraction digits to be used. Either none or both of these properties are present; if they are, they override minimum and maximum integer and fraction digits.
  • [[RoundingType]] is one of the values fractionDigits, significantDigits, morePrecision, or lessPrecision, indicating which rounding strategy to use, as discussed in .
  • [[RoundingMode]] is one of the String values in the Identifier column of , specifying which rounding mode to use.
  • [[RoundingIncrement]] is an integer-valued Number that evenly divides 10, 100, 1000, or 10000 into tenths, fifths, quarters, or halves. It indicates the increment at which rounding should take place relative to the calculated rounding magnitude. For example, if [[MaximumFractionDigits]] is 2 and [[RoundingIncrement]] is 5, then the number is rounded to the nearest 0.05 ("nickel rounding").
  • [[TrailingZeroDisplay]] is one of the String values "auto" or "stripIfInteger", indicating whether to strip trailing zeros if the formatted number is an integer (i.e., has no nonzero fraction digit).

1.5 Abstract Operations for PluralRules Objects

1.5.1 GetOperands ( s )

The abstract operation GetOperands takes argument s (a decimal String). It extracts numeric features from s that correspond with the operands of Unicode Technical Standard #35 Part 3 Numbers, Section 5.1.1 Operands. It performs the following steps when called:

  1. Let n be ! ToNumber(s).
  2. Assert: n is finite.
  3. Let dp be StringIndexOf(s, ".", 0).
  4. If dp = -1, then
    1. Let intPart be n.
    2. Let fracSlice be "".
  5. Else,
    1. Let intPart be the substring of s from 0 to dp.
    2. Let fracSlice be the substring of s from dp + 1.
  6. Let i be abs(! ToNumber(intPart)).
  7. Let fracDigitCount be the length of fracSlice.
  8. Let f be ! ToNumber(fracSlice).
  9. Let significantFracSlice be the value of fracSlice stripped of trailing "0".
  10. Let significantFracDigitCount be the length of significantFracSlice.
  11. Let significantFrac be ! ToNumber(significantFracSlice).
  12. Return a new Record { [[Number]]: abs(n), [[IntegerDigits]]: i, [[FractionDigits]]: f, [[NumberOfFractionDigits]]: fracDigitCount, [[FractionDigitsWithoutTrailing]]: significantFrac, [[NumberOfFractionDigitsWithoutTrailing]]: significantFracDigitCount }.
Table 2: Plural Rules Operands Record Fields
Internal Slot Type UTS #35 Operand Description
[[Number]] Number n Absolute value of the source number
[[IntegerDigits]] Number i Integer part of [[Number]].
[[FractionDigits]] Number f Visible fraction digits in [[Number]], with trailing zeroes, as an integer having [[NumberOfFractionDigits]] digits.
[[NumberOfFractionDigits]] Number v Number of visible fraction digits in [[Number]], with trailing zeroes.
[[FractionDigitsWithoutTrailing]] Number t Visible fraction digits in [[Number]], without trailing zeroes, as an integer having [[NumberOfFractionDigitsWithoutTrailing]] digits.
[[NumberOfFractionDigitsWithoutTrailing]] Number w Number of visible fraction digits in [[Number]], without trailing zeroes.

1.5.2 PluralRuleSelect ( locale, type, n, operands )

The implementation-defined abstract operation PluralRuleSelect takes arguments locale (a String), type (a String), n (a finite Number), and operands (a Plural Rules Operands Record derived from formatting n). It returns the String from « "zero", "one", "two", "few", "many", "other" » that best categorizes the operands representation of n according to the rules for locale and type.

1.5.3 ResolvePlural ( pluralRules, n )

When the ResolvePlural abstract operation is called with arguments pluralRules (which must be an object initialized as a PluralRules) and n (which must be a Number value), it returns a Record containing two values: a String value representing the plural form of n according to the effective locale and the options of pluralRules in the field [[PluralCategory]], and n as a formatted string in the field [[FormattedString]]. The following steps are taken:

  1. Assert: Type(pluralRules) is Object.
  2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
  3. Assert: Type(n) is Number.
  4. If n is not a finite Number, then
    1. Return "other".
  5. Let locale be pluralRules.[[Locale]].
  6. Let type be pluralRules.[[Type]].
  7. Let res be ! FormatNumericToString(pluralRules, n).
  8. Let s be res.[[FormattedString]].
  9. Let operands be ! GetOperands(s).
  10. Let p be ! PluralRuleSelect(locale, type, n, operands).
  11. Return the Record { [[PluralCategory]]: p, [[FormattedString]]: s }.

1.5.4 PluralRuleSelectRange ( locale, type, xp, yp )

When the PluralRuleSelectRange abstract operation is called with four arguments, it performs an implementation-dependent algorithm to map the plural form String values xp and yp, representing the plural forms of the start and end of a range, to a resolved String value for the plural form of the range as a whole denoted by type for the corresponding locale, or the String value "other".

1.5.5 ResolvePluralRange ( pluralRules, x, y )

When the ResolvePluralRange abstract operation is called with arguments pluralRules (which must be an object initialized as a PluralRules), x (which must be a Number value), and y (which must be a Number value), it returns a String value representing the plural form of the range starting from x and ending at y according to the effective locale and the options of pluralRules. The following steps are taken:

  1. Assert: Type(pluralRules) is Object.
  2. Assert: pluralRules has an [[InitializedPluralRules]] internal slot.
  3. Assert: Type(x) is Number.
  4. Assert: Type(y) is Number.
  5. If x is NaN or y is NaN, throw a RangeError exception.
  6. Let xp be ! ResolvePlural(pluralRules, x).
  7. Let yp be ! ResolvePlural(pluralRules, y).
  8. If xp.[[FormattedString]] is yp.[[FormattedString]], then
    1. Return xp.[[PluralCategory]].
  9. Let locale be pluralRules.[[Locale]].
  10. Let type be pluralRules.[[Type]].
  11. Return ! PluralRuleSelectRange(locale, type, xp.[[PluralCategory]], yp.[[PluralCategory]]).