JavaScript pluralize an english string

前端 未结 11 1004
南旧
南旧 2020-12-23 16:24

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 grea

相关标签:
11条回答
  • 2020-12-23 16: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

    0 讨论(0)
  • 2020-12-23 16:46

    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.

    0 讨论(0)
  • 2020-12-23 16:49

    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
    
    0 讨论(0)
  • 2020-12-23 16:50

    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.

    0 讨论(0)
  • 2020-12-23 16:53

    I use this simple inline statement

    const number = 2;
    const string = `${number} trutle${number === 1 ? "" : "s"}`; //this one
    console.log(string)

    0 讨论(0)
  • 2020-12-23 16:54

    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
    }
    
    0 讨论(0)
提交回复
热议问题