24 Pluralization

Programs often need to create output strings that contain different words/phrases depending on the value of an associated integer. There are many different ways to solve this problem, but most of them are awkward, at best.

Motivation

For example, suppose you are writing a program for a local animal shelter that must produce the output “There is 1 poodle available for adoption.” when they have one poodle and “There are 3 poodles available for adoption.” when they have three poodles. There are two differences between these two sentences: the “is”/ “are” distinction and the “poodle”/ “poodles” distinction, both of which can be thought of as pluralization problems.

Review

You could, of course, treat this as an isolated problem. For example, assuming the variable n contains the number of poodles, you could solve this problem as follows:

        if (n == 1) {
            result = "There is 1 poodle available for adoption.";
        } else {
            result = "There are " + n + " poodles available for adoption.";
        }

However, the amount of duplication in the two String literals makes this solution prone to error; typing them both exactly as wanted is difficult and it is easy to make mistakes when copying, pasting, and editing the copy. Hence, you might instead solve this specific problem as follows:

        result = "There";

        if (n == 1) result += " is";
        else        result += " are";
        
        result += " " + n + " poodle";
        
        if (n > 1) result += "s";
        
        result += " available for adoption.";

Unfortunately, it’s easy to get careless (and lazy) in situations like this. Hence, it would be nice to have a more generic solution.

Thinking About The Problem

You’d probably like to be able to construct a String in one form (e.g., the singular) and then invoke a method (e.g., pluralize()) that converts it to the other form (e.g., the plural). However, this kind of natural language processing (NLP) problem is very difficult to solve, and such a method would be far too computationally burdensome and unreliable for most applications.[1] Fortunately, however, you speak English and are very good at converting from one form to another. So, the solution to the problem is to harness your ability to pluralize in a convenient way.

The Pattern

The solution starts with a simple method that returns either the singular or plural form of a word (both of which you provide to the method), based on the value of another parameter:

    public static String form(int n, String singular, String plural) {
        if (n > 1) return plural;
        else       return singular;
    }

Then, you simply create a bunch of specific methods that use this method.

Examples

Continuing with the animal shelter example, you first need the following method for the word “is”/ “are”:

    public static String is(int n) {
        return form(n, "is", "are");
    }

You then need the following method for adding an “s” to regular nouns:

    public static String regular(int n, String noun) {
        return noun + form(n, "", "s");
    }

Assuming all of these methods are in a class named Pluralize, they can then be used with a regular noun like “poodle” as follows:

        result = "There " + Pluralize.is(n) + " "
            + n + " " + Pluralize.regular(n, "poodle")
            + " available for adoption.";

and with an irregular noun like “mouse” as follows:

        result = "There " + Pluralize.is(n) + " "
            + n + " " + Pluralize.form(n, "mouse", "mice")
            + " available for adoption.";

Finally, an irregular noun like “sheep” could either be handled as in the “mouse” example, or as follows:

        result = "There " + Pluralize.is(n) + " "
            + n + " sheep available for adoption.";

  1. An artificial/contrived solution of this kind is sometimes called a Deus ex machina, which is Latin for "god from the machine".

License

Icon for the Creative Commons Attribution 4.0 International License

Patterns for Beginning Programmers by David Bernstein is licensed under a Creative Commons Attribution 4.0 International License, except where otherwise noted.

Share This Book