73

In PHP, I use Kuwamoto's class to pluralize nouns in my strings. I didn't find something as good as this script in javascript except for some plugins. So, it would be great to have a javascript function based on Kuwamoto's class.

http://kuwamoto.org/2007/12/17/improved-pluralizing-in-php-actionscript-and-ror/

cloned
  • 6,346
  • 4
  • 26
  • 38
pmrotule
  • 9,065
  • 4
  • 50
  • 58

15 Answers15

101

Simple version (ES6):

const pluralize = (count, noun, suffix = 's') =>
  `${count} ${noun}${count !== 1 ? suffix : ''}`;

Typescript:

const pluralize = (count: number, noun: string, suffix = 's') =>
  `${count} ${noun}${count !== 1 ? suffix : ''}`;

Usage:

pluralize(0, 'turtle'); // 0 turtles
pluralize(1, 'turtle'); // 1 turtle
pluralize(2, 'turtle'); // 2 turtles
pluralize(3, 'fox', 'es'); // 3 foxes

This obviously doesn't support all english edge-cases, but it's suitable for most purposes

Kabir Sarin
  • 18,092
  • 10
  • 50
  • 41
78

Use Pluralize

There's a great little library called Pluralize that's packaged in npm and bower.

This is what it looks like to use:

import Pluralize from 'pluralize';

Pluralize( 'Towel', 42 );       // "Towels"

Pluralize( 'Towel', 42, true ); // "42 Towels"

And you can get it here:

https://github.com/blakeembrey/pluralize

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
  • thanks @JoshuaPinter, I was handling s then ies, with a custom function then thought there has to be something out there, exactly what I was looking for. – ak85 May 28 '18 at 09:35
  • 3
    @ak85 Adding another dependency isn't always the solution, but when it's something like this, that is easy to understand and isn't critical, it makes a lot of sense. Standing on the shoulders of giants. – Joshua Pinter May 28 '18 at 11:58
45

So, I answer my own question by sharing my translation in javascript of Kuwamoto's PHP class.

String.prototype.plural = function(revert){

    var plural = {
        '(quiz)$'               : "$1zes",
        '^(ox)$'                : "$1en",
        '([m|l])ouse$'          : "$1ice",
        '(matr|vert|ind)ix|ex$' : "$1ices",
        '(x|ch|ss|sh)$'         : "$1es",
        '([^aeiouy]|qu)y$'      : "$1ies",
        '(hive)$'               : "$1s",
        '(?:([^f])fe|([lr])f)$' : "$1$2ves",
        '(shea|lea|loa|thie)f$' : "$1ves",
        'sis$'                  : "ses",
        '([ti])um$'             : "$1a",
        '(tomat|potat|ech|her|vet)o$': "$1oes",
        '(bu)s$'                : "$1ses",
        '(alias)$'              : "$1es",
        '(octop)us$'            : "$1i",
        '(ax|test)is$'          : "$1es",
        '(us)$'                 : "$1es",
        '([^s]+)$'              : "$1s"
    };

    var singular = {
        '(quiz)zes$'             : "$1",
        '(matr)ices$'            : "$1ix",
        '(vert|ind)ices$'        : "$1ex",
        '^(ox)en$'               : "$1",
        '(alias)es$'             : "$1",
        '(octop|vir)i$'          : "$1us",
        '(cris|ax|test)es$'      : "$1is",
        '(shoe)s$'               : "$1",
        '(o)es$'                 : "$1",
        '(bus)es$'               : "$1",
        '([m|l])ice$'            : "$1ouse",
        '(x|ch|ss|sh)es$'        : "$1",
        '(m)ovies$'              : "$1ovie",
        '(s)eries$'              : "$1eries",
        '([^aeiouy]|qu)ies$'     : "$1y",
        '([lr])ves$'             : "$1f",
        '(tive)s$'               : "$1",
        '(hive)s$'               : "$1",
        '(li|wi|kni)ves$'        : "$1fe",
        '(shea|loa|lea|thie)ves$': "$1f",
        '(^analy)ses$'           : "$1sis",
        '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': "$1$2sis",        
        '([ti])a$'               : "$1um",
        '(n)ews$'                : "$1ews",
        '(h|bl)ouses$'           : "$1ouse",
        '(corpse)s$'             : "$1",
        '(us)es$'                : "$1",
        's$'                     : ""
    };

    var irregular = {
        'move'   : 'moves',
        'foot'   : 'feet',
        'goose'  : 'geese',
        'sex'    : 'sexes',
        'child'  : 'children',
        'man'    : 'men',
        'tooth'  : 'teeth',
        'person' : 'people'
    };

    var uncountable = [
        'sheep', 
        'fish',
        'deer',
        'moose',
        'series',
        'species',
        'money',
        'rice',
        'information',
        'equipment'
    ];

    // save some time in the case that singular and plural are the same
    if(uncountable.indexOf(this.toLowerCase()) >= 0)
      return this;

    // check for irregular forms
    for(word in irregular){

      if(revert){
              var pattern = new RegExp(irregular[word]+'$', 'i');
              var replace = word;
      } else{ var pattern = new RegExp(word+'$', 'i');
              var replace = irregular[word];
      }
      if(pattern.test(this))
        return this.replace(pattern, replace);
    }

    if(revert) var array = singular;
         else  var array = plural;

    // check for matches using regular expressions
    for(reg in array){

      var pattern = new RegExp(reg, 'i');

      if(pattern.test(this))
        return this.replace(pattern, array[reg]);
    }

    return this;
}

Easy to use:

alert("page".plural()); // return plural form => pages
alert("mouse".plural()); // return plural form => mice
alert("women".plural(true)); // return singular form => woman

DEMO

pmrotule
  • 9,065
  • 4
  • 50
  • 58
  • 9
    Extending built-in object prototypes is usually not a good idea. You might want to take a look at this module: https://github.com/blakeembrey/pluralize – Paolo Moretti Nov 28 '14 at 19:03
  • 1
    There is a small error in the plural array. The last item should be `'$' : 's'` instead of `'s$' : 's'` – wout Nov 02 '15 at 15:13
  • @wout - You're right, my bad! I changed it to `'(.)$' : '$1s'` to be sure there's at least one character in the string – pmrotule Nov 09 '15 at 18:58
  • @pmrotule Still a problem though. With `'(.)$' : '$1s'` pluralizing `page` would result in `pags`. So I converted back to `'$' : '$1s'` and added one rule above in case of an empty string: `'^$' : ''`. Now it works as expected on my side. – wout Nov 10 '15 at 08:42
  • @wout - That's weird. With `$1`, it's not supposed to replace any of the existing character. It works well for me (`page` will result in `pages` - see demo). Still a problem though, if it is already plural, it will result in `pagess` so I modified it to `'([^s]+)$' : '$1s'` – pmrotule Nov 11 '15 at 19:06
  • What about the word "I"? That produces "Is" which is incorrect. I'd add it to the uncountable. – Nate Feb 05 '16 at 15:52
  • @Nate Like any other word that isn't a noun, it will produce nonsense : "where" = "wheres", "they" = "theys", "already" = "alreadies", etc. – pmrotule Feb 05 '16 at 23:32
  • You need to add moose to the list of uncountables – soapergem May 05 '16 at 20:20
  • 1
    @SoaperGEM - I am Canadian and I forgot that one. Shame on me! I edited the uncountables. – pmrotule May 06 '16 at 13:57
  • Also, two other cases it doesn't handle correctly: **data** (although it does handle datum correctly!) and **alumnus** vs. **alumni** – soapergem May 06 '16 at 16:50
  • I like this, I realise it was posted ages ago! I've added `if (revert != undefined && !isNaN(revert)) { // if revert is passed in as a number, we will pluralise if >1 or singularise if <=1 revert = (revert * 1) <= 1; };` so we can pass in an integer to pluralise based on count – Jamie Hartnoll Sep 27 '16 at 13:53
  • this approach is not perfect. Some of the words that was already in plural form still transform to plural form. Try `data` – Rich Apr 02 '19 at 03:23
  • "Octopi" is not standard English – it is based on the incorrect assumption that the Latin noun "octopus" is 2nd declension (when in fact it is third). The standard English plural is "octopuses". The proper Latin plural is "octopodes", which is very occasionally used in English, but most consider that usage to be overly Latinate. Similarly, "viri" as plural for "virus" is both bad English and bad Latin; the standard English plural is "viruses". "Octopi" and "viri" come across as someone trying to sound educated without actually being so. – Simon Kissane Apr 16 '21 at 07:31
24

Based on @pmrotule answer with some typescript magic and some additions to the uncountable array. I add here the plural and singular functions.

The plural version:

/**
 * Returns the plural of an English word.
 *
 * @export
 * @param {string} word
 * @param {number} [amount]
 * @returns {string}
 */
export function plural(word: string, amount?: number): string {
    if (amount !== undefined && amount === 1) {
        return word
    }
    const plural: { [key: string]: string } = {
        '(quiz)$'               : "$1zes",
        '^(ox)$'                : "$1en",
        '([m|l])ouse$'          : "$1ice",
        '(matr|vert|ind)ix|ex$' : "$1ices",
        '(x|ch|ss|sh)$'         : "$1es",
        '([^aeiouy]|qu)y$'      : "$1ies",
        '(hive)$'               : "$1s",
        '(?:([^f])fe|([lr])f)$' : "$1$2ves",
        '(shea|lea|loa|thie)f$' : "$1ves",
        'sis$'                  : "ses",
        '([ti])um$'             : "$1a",
        '(tomat|potat|ech|her|vet)o$': "$1oes",
        '(bu)s$'                : "$1ses",
        '(alias)$'              : "$1es",
        '(octop)us$'            : "$1i",
        '(ax|test)is$'          : "$1es",
        '(us)$'                 : "$1es",
        '([^s]+)$'              : "$1s"
    }
    const irregular: { [key: string]: string } = {
        'move'   : 'moves',
        'foot'   : 'feet',
        'goose'  : 'geese',
        'sex'    : 'sexes',
        'child'  : 'children',
        'man'    : 'men',
        'tooth'  : 'teeth',
        'person' : 'people'
    }
    const uncountable: string[] = [
        'sheep',
        'fish',
        'deer',
        'moose',
        'series',
        'species',
        'money',
        'rice',
        'information',
        'equipment',
        'bison',
        'cod',
        'offspring',
        'pike',
        'salmon',
        'shrimp',
        'swine',
        'trout',
        'aircraft',
        'hovercraft',
        'spacecraft',
        'sugar',
        'tuna',
        'you',
        'wood'
    ]
    // save some time in the case that singular and plural are the same
    if (uncountable.indexOf(word.toLowerCase()) >= 0) {
        return word
    }
    // check for irregular forms
    for (const w in irregular) {
        const pattern = new RegExp(`${w}$`, 'i')
        const replace = irregular[w]
        if (pattern.test(word)) {
            return word.replace(pattern, replace)
        }
    }
    // check for matches using regular expressions
    for (const reg in plural) {
        const pattern = new RegExp(reg, 'i')
        if (pattern.test(word)) {
            return word.replace(pattern, plural[reg])
        }
    }
    return word
}

And the singular version:

/**
 * Returns the singular of an English word.
 *
 * @export
 * @param {string} word
 * @param {number} [amount]
 * @returns {string}
 */
export function singular(word: string, amount?: number): string {
    if (amount !== undefined && amount !== 1) {
        return word
    }
    const singular: { [key: string]: string } = {
        '(quiz)zes$'             : "$1",
        '(matr)ices$'            : "$1ix",
        '(vert|ind)ices$'        : "$1ex",
        '^(ox)en$'               : "$1",
        '(alias)es$'             : "$1",
        '(octop|vir)i$'          : "$1us",
        '(cris|ax|test)es$'      : "$1is",
        '(shoe)s$'               : "$1",
        '(o)es$'                 : "$1",
        '(bus)es$'               : "$1",
        '([m|l])ice$'            : "$1ouse",
        '(x|ch|ss|sh)es$'        : "$1",
        '(m)ovies$'              : "$1ovie",
        '(s)eries$'              : "$1eries",
        '([^aeiouy]|qu)ies$'     : "$1y",
        '([lr])ves$'             : "$1f",
        '(tive)s$'               : "$1",
        '(hive)s$'               : "$1",
        '(li|wi|kni)ves$'        : "$1fe",
        '(shea|loa|lea|thie)ves$': "$1f",
        '(^analy)ses$'           : "$1sis",
        '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': "$1$2sis",
        '([ti])a$'               : "$1um",
        '(n)ews$'                : "$1ews",
        '(h|bl)ouses$'           : "$1ouse",
        '(corpse)s$'             : "$1",
        '(us)es$'                : "$1",
        's$'                     : ""
    }
    const irregular: { [key: string]: string } = {
        'move'   : 'moves',
        'foot'   : 'feet',
        'goose'  : 'geese',
        'sex'    : 'sexes',
        'child'  : 'children',
        'man'    : 'men',
        'tooth'  : 'teeth',
        'person' : 'people'
    }
    const uncountable: string[] = [
        'sheep',
        'fish',
        'deer',
        'moose',
        'series',
        'species',
        'money',
        'rice',
        'information',
        'equipment',
        'bison',
        'cod',
        'offspring',
        'pike',
        'salmon',
        'shrimp',
        'swine',
        'trout',
        'aircraft',
        'hovercraft',
        'spacecraft',
        'sugar',
        'tuna',
        'you',
        'wood'
    ]
    // save some time in the case that singular and plural are the same
    if (uncountable.indexOf(word.toLowerCase()) >= 0) {
        return word
    }
    // check for irregular forms
    for (const w in irregular) {
        const pattern = new RegExp(`${irregular[w]}$`, 'i')
        const replace = w
        if (pattern.test(word)) {
            return word.replace(pattern, replace)
        }
    }
    // check for matches using regular expressions
    for (const reg in singular) {
        const pattern = new RegExp(reg, 'i')
        if (pattern.test(word)) {
            return word.replace(pattern, singular[reg])
        }
    }
    return word
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Erik Campobadal
  • 867
  • 9
  • 14
  • Thanks for cleaning it up. So many answers would benefit from pure and closed-form functions like this. ❤️ – Gleno Dec 30 '19 at 13:18
  • just the perfect answer, here's how you can do it in Angular: https://gist.github.com/ezzabuzaid/1d49eac3c2887702636c0975a3a06ace – Ezzabuzaid Dec 08 '20 at 10:33
  • Fuses returns fus not fuse. Uses returns us not use. – rory.ap Nov 04 '22 at 21:01
7

The new intl API spec from ECMA will provide the plural rules function, https://github.com/tc39/proposal-intl-plural-rules

Here's the polyfill that can be used today https://github.com/eemeli/IntlPluralRules

gasolin
  • 2,196
  • 1
  • 18
  • 20
7

Taken from my blog: https://sergiotapia.me/pluralizing-strings-in-javascript-es6-b5d4d651d403


You can use the pluralize library for this.

NPM:
npm install pluralize --save

Yarn:
yarn add pluralize

Wherever you want to use the lib, you can require it easily.

var pluralize = require('pluralize')

I like to add it to the window object so I can just invoke pluralize() wherever I need it. Within my application.js root file:

window.pluralize = require('pluralize')

Then you can just use it anywhere, React components, or just plain Javascript:

<span className="pull-left">
  {`${item.score} ${pluralize('point', item.score)}`}
</span>

console.log(pluralize('point', item.score))
Sergio Tapia
  • 9,173
  • 12
  • 35
  • 59
7

I use this simple inline statement

const number = 2;
const string = `${number} trutle${number === 1 ? "" : "s"}`; //this one
console.log(string)
Tudor Morar
  • 3,720
  • 2
  • 27
  • 25
2

I’ve created a very simple library that can be used for words pluralization in JavaScript. It transparently uses CLDR database for multiple locales, so it supports almost any language you would like to use. It’s API is very minimalistic and integration is extremely simple. It’s called Numerous.

I’ve also written a small introduction article to it: «How to pluralize any word in different languages using JavaScript?».

Feel free to use it in your project. I will also be glad for your feedback on it.

Slava Fomin II
  • 26,865
  • 29
  • 124
  • 202
2

To provide a simple and readable option (ES6):

export function pluralizeAndStringify(value, word, suffix = 's'){
   if (value == 1){
    return value + ' ' + word;
   }
   else {
    return value + ' ' + word + suffix;
   }
}

If you gave something like pluralizeAndStringify(5, 'dog') you'd get "5 dogs" as your output.

kmypwn
  • 437
  • 1
  • 6
  • 17
2

Use -ies or -s (depending on the second-to-last letter) if the word ends in a y, use -es if the word ends in a ‑s, -ss, -sh, -ch, -x, or -z, use a lookup table if the world is an irregular plural, and use -s otherwise.

var pluralize = (function () {
    const vowels = "aeiou";

    const irregulars = { "addendum": "addenda", "aircraft": "aircraft", "alumna": "alumnae", "alumnus": "alumni", "analysis": "analyses", "antenna": "antennae", "antithesis": "antitheses", "apex": "apices", "appendix": "appendices", "axis": "axes", "bacillus": "bacilli", "bacterium": "bacteria", "basis": "bases", "beau": "beaux", "bison": "bison", "bureau": "bureaux", "cactus": "cacti", "château": "châteaux", "child": "children", "codex": "codices", "concerto": "concerti", "corpus": "corpora", "crisis": "crises", "criterion": "criteria", "curriculum": "curricula", "datum": "data", "deer": "deer", "diagnosis": "diagnoses", "die": "dice", "dwarf": "dwarves", "ellipsis": "ellipses", "erratum": "errata", "faux pas": "faux pas", "fez": "fezzes", "fish": "fish", "focus": "foci", "foot": "feet", "formula": "formulae", "fungus": "fungi", "genus": "genera", "goose": "geese", "graffito": "graffiti", "grouse": "grouse", "half": "halves", "hoof": "hooves", "hypothesis": "hypotheses", "index": "indices", "larva": "larvae", "libretto": "libretti", "loaf": "loaves", "locus": "loci", "louse": "lice", "man": "men", "matrix": "matrices", "medium": "media", "memorandum": "memoranda", "minutia": "minutiae", "moose": "moose", "mouse": "mice", "nebula": "nebulae", "nucleus": "nuclei", "oasis": "oases", "offspring": "offspring", "opus": "opera", "ovum": "ova", "ox": "oxen", "parenthesis": "parentheses", "phenomenon": "phenomena", "phylum": "phyla", "quiz": "quizzes", "radius": "radii", "referendum": "referenda", "salmon": "salmon", "scarf": "scarves", "self": "selves", "series": "series", "sheep": "sheep", "shrimp": "shrimp", "species": "species", "stimulus": "stimuli", "stratum": "strata", "swine": "swine", "syllabus": "syllabi", "symposium": "symposia", "synopsis": "synopses", "tableau": "tableaux", "thesis": "theses", "thief": "thieves", "tooth": "teeth", "trout": "trout", "tuna": "tuna", "vertebra": "vertebrae", "vertex": "vertices", "vita": "vitae", "vortex": "vortices", "wharf": "wharves", "wife": "wives", "wolf": "wolves", "woman": "women", "guy": "guys", "buy": "buys", "person": "people" };

    function pluralize(word) {
        word = word.toLowerCase();


        if (irregulars[word]) {
            return irregulars[word];
        }

        if (word.length >= 2 && vowels.includes(word[word.length - 2])) {
            return word + "s";
        }

        if (word.endsWith("s") || word.endsWith("sh") || word.endsWith("ch") || word.endsWith("x") || word.endsWith("z")) {
            return word + "es";
        }

        if (word.endsWith("y")) {
            return word.slice(0, -1) + "ies";
        }


        return word + "s";
    }

    return pluralize;
})();

////////////////////////////////////////
console.log(pluralize("dog"));
console.log(pluralize("cat"));
console.log(pluralize("fox"));
console.log(pluralize("dwarf"));
console.log(pluralize("guy"));
console.log(pluralize("play"));

Obviously, this can't support all English edge-cases, but it has the most common ones.

Nirvana
  • 405
  • 3
  • 15
  • Needs a more generic test for words ending in 'y' where the second to last letter is a vowel. You're checking for 'guy' and 'buy' but I believe it should be generalized, to include all others, such as 'day'. `if (word.length >= 2 && word[word.length - 2].toLowerCase().match(/[aeiou]/gi)) { return word + 's'; }` – Andrew McGrath May 26 '22 at 14:08
  • @AndrewMcGrath I fixed it in an edit now. – Nirvana May 29 '22 at 07:32
1
function pluralize( /* n, [ n2, n3, ... ] str */ ) {
    var n = Array.prototype.slice.call( arguments ) ;
    var str = n.pop(), iMax = n.length - 1, i = -1, j ;
    str = str.replace( /\$\$|\$(\d+)/g,
        function( m, p1 ) { return m == '$$' ? '$' : n[+p1-1] }
    ) ;
    return str.replace( /[(](.*?)([+-])(\d*)(?:,([^,)]*))?(?:,([^)]*))?[)]/g,
        function( match, one, sign, abs, not1, zero ) {
            // if abs, use indicated element in the array of numbers
            // instead of using the next element in sequence
            abs ? ( j = +abs - 1 ) : ( i < iMax && i++, j = i ) ;
            if ( zero != undefined && n[j] == 0 ) return zero ;
            return ( n[j] != 1 ) == ( sign == '+' ) ? ( not1 || 's' ) : one ;
        }
    ) ;  
}

console.log( pluralize( 1, 'the cat(+) live(-) outside' ) ) ;
// the cat lives outside
console.log( pluralize( 2, 'the child(+,ren) (is+,are) inside' ) ) ;
// the children are inside
console.log( pluralize( 0, '$1 dog(+), ($1+,$1,no) dog(+), ($1+,$1,no) dog(+,,)' ) ) ;
// 0 dogs, no dogs, no dog
console.log( pluralize( 100, 1, '$1 penn(y+,ies) make(-1) $$$2' ) ) ;
// 100 pennies make $1
console.log( pluralize( 1, 0.01, '$1 penn(y+,ies) make(-1) $$$2' ) ) ;
// 1 penny makes $0.01
barncat
  • 87
  • 1
  • 4
  • 3
    Proving on the code for the solution is not encouraged. Kindly provide the explanation solution, how it solves the problem. – Mittal Patel Jul 11 '18 at 19:14
1

Using @sarink's answer, I made a function to create a string using key value pairs data and pluralizing the keys. Here's the snippet:

// Function to create a string from given key value pairs and pluralize keys
const stringPluralize = function(data){
    var suffix = 's';
    var str = '';
    $.each(data, function(key, val){
        if(str != ''){
            str += val>0 ? ` and ${val} ${key}${val !== 1 ? suffix : ''}` : '';
        }
        else{
            str = val>0 ? `${val} ${key}${val !== 1 ? suffix : ''}` : '';
        }
    });
    return str;
}
var leftDays = '1';
var leftHours = '12';
var str = stringPluralize({day:leftDays, hour:leftHours});
console.log(str) // Gives 1 day and 12 hours
Chintan Bhatt
  • 183
  • 1
  • 6
0

I am late to the party too, but this will work for English words or Spanish:

String.prototype.pluralize = function(count, plural = 's') {
  return count === 1 ? this : plural.length > 2 ? plural : this + plural
};

This way you can use any string like so:

"Apple".pluralize(1) // Apple
"Apple".pluralize(2) // Apples
"Company".pluralize(1, "Companies") // Company
"Company".pluralize(5, "Companies") // Companies
"Tooth".pluralize(1, "Teeth") // Tooth
"Tooth".pluralize(2, "Teeth") // Teeth 

Some Spanish:

"arbol".pluralize(1,"es")  // arbol
"arbol".pluralize(2,"es")  // arboles
"manzana".pluralize(1) // manzana
"manzana".pluralize(2) // manzanas
-1

In case the singular/plural word is not dynamic and you just want to add an "s" if there's more than one:

`${x} minute${x - 1 ? 's' : ''}`
Oded Breiner
  • 28,523
  • 10
  • 105
  • 71
-1

I'm a bit late to this party but this works nicely with very minimal code:

const pluralize = (count, single, plural) => `${count} ${count !== 1 ? plural || single+'s' : single}`;

Provide either a single word:

pluralize(1, 'house');
// Output: 1 house

pluralize(2, 'house');
// Output: 2 houses

or, 2 strings for words with different endings:

pluralize(1, 'company', 'companies');
// Output: 1 company

pluralize(2, 'company', 'companies');
// Output: 2 companies

pluralize(100000, "fish", "fish");
// Output: 100000 fish

pluralize(2, "piece of furniture", "pieces of furniture");
// Output: 2 pieces of furniture
Must Impress
  • 339
  • 2
  • 4
  • There are many words that do not have only the letter s added at the end, these words can be completely different words, that nothing is added to them, or that something else is added besides s. For example firmware, fish, furniture, gold, hardware. – MrEduar Aug 25 '23 at 20:03
  • If you look at my code you'll see that it doesn't simply pump out an "s" at the end of the String if it's plural. It uses a plural parameter value if one is supplied. If not, then it adds an "s" to the single parameter value. So, for all of your examples, you simply use pluralize(count, "fish", "fish"), pluralize(2, "piece of furniture", "pieces of furniture"), etc... – Must Impress Aug 27 '23 at 16:17