Text

Plurals

When writing software, it is often the tasks that appear trivial which can prove to be rather problematic. In this article we’ll have a look at creating plural strings which, on the surface looks easy, but can cause some unforeseen problems when it comes to actually implementing it.

Let’s start with a really simple example. We want to create a string detailing a number of items. When there is a single item, we want to display “1 item”; otherwise we want to display “x items”. This can be achieved quite easily:

[java] String.format(
value == 1 ? “%d item ” : “%d items “,
value );
[/java]

This code does precisely what we need. However we can hit problems if we need to internationalise our app so that we display a string localised to the language setting of the device. To those developers like me for whom English is their first and only language, this seems rather easy. Android provides internationalisation through its resource management framework which allows us to simply provide strings.xml for each language that we need to support. We just look up the string by resource ID, and the OS will take care of returning the correct language based upon the device localisation settings.

While this is technically correct, there is one major flaw: Not all languages follow the same pluralisation rules as English. Our code assumes that all languages use one form of the noun (in our example “item”) when there is only one object, and a second form (in our example “items”) for all other cases. While this is true for some other languages, it is certainly not true for many others.

If we now look back at the earlier code we can see that we’ll need to change the conditional logic to cope with different plural rules for different languages. But hang on a second – doesn’t this seem a bit wrong? We’re not having to worry about getting the correct translation, but we then have to determine the language so we can apply the correct pluralisation rules.

Fortunately we do not have to do this because there is actually a pluralisation engine built in to Android resource management which will do this for us. We can use this by defining a plural definition in strings.xml, or plurals.xml, if you prefer:

[xml] No items
1 item
%d items
[/xml]

Notice how we also define a special form for zero items, as well here. For full details of the quantity types that can be specified please refer to the official documentation.

Once defined we can either lookup the correct form for a given value and perform the formatting ourselves:

[java] String fmt = getResources().getQuantityString( resource, value );
String out = String.format( fmt, value );
[/java]

Or we can get a fully formatted string:

[java] String out = getResources().getQuantityString( resource, value, value );
[/java]

As a final example, let’s use a plurals definition to create an age string based upon the rules defined here. In res/values/strings.xml:

[xml] 1 year old
%d years old
[/xml]

and in res/values-ru/strings.xml:

[xml] 1 лет
%d года
%d лет
[/xml]

If we set the device to English we’ll get:

[code] 1 year old 18 years old 23 years old
[/code]

but if we switch to Russian we’ll get:

[code] 1 лет 18 года 23 лет
[/code]

This being a technical blog I have not delved in to some of the complexities of pluralisation in specific languages, but really given an overview of the tools which are available within Android to handle much of the burden of pluralising strings. Source code demonstrating the techniques discussed in this article can be found here.

N.B. Since this article was written, Wolfram Rittmeyer has published an article on plurals on Grokking Andorid which contains some information on some of the pitfalls with using plurals.

© 2012, Mark Allison. All rights reserved.

Copyright © 2012 Styling Android. All Rights Reserved.
Information about how to reuse or republish this work may be available at http://blog.stylingandroid.com/license-information.

5 Comments

  1. Great article! Also, could you please stop this cookie nonsense? Noone care. Really not a single soul 🙂

    1. I’m merely conforming to EU law. I’m obliged to request permission before using cookies and that’s what I have to do or risk being shut down. I personally think this law it totally stupid, but I have to comply nonetheless.

  2. This is really useful and a much more robust way of handling pluralisation. Even in English you can’t always really on adding an ‘s’, as with child and children.

  3. The sample is a bit incorrect. XML should be
    ===

    1 год
    %d года
    %d лет

    ===
    And test results should be (in article all incorrect):
    ===
    1 год 18 лет 23 года
    ===

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.