Archive for October, 2009

Post

Pluralization Helper for C#

In .Net, Rails on October 28, 2009 by Matt Grande Tagged: , , ,

I recently wanted a pluralization inflector in a C# project, one similar to the one in Ruby on Rails. Unable to find a satisfactory one, I whipped up my own. Here’s what I’ve got.

namespace MyNamespace
{
    public class Formatting
    {
        private static readonly IList<string> Unpluralizables = new List<string>
        { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "deer" };
        private static readonly IDictionary<string, string> Pluralizations = new Dictionary<string, string>
        {
            // Start with the rarest cases, and move to the most common
            { "person", "people" },
            { "ox", "oxen" },
            { "child", "children" },
            { "foot", "feet" },
            { "tooth", "teeth" },
            { "goose", "geese" },
            // And now the more standard rules.
            { "(.*)fe?", "$1ves" },         // ie, wolf, wife
            { "(.*)man$", "$1men" },
            { "(.+[aeiou]y)$", "$1s" },
            { "(.+[^aeiou])y$", "$1ies" },
            { "(.+z)$", "$1zes" },
            { "([m|l])ouse$", "$1ice" },
            { "(.+)(e|i)x$", @"$1ices"},    // ie, Matrix, Index
            { "(octop|vir)us$", "$1i"},
            { "(.+(s|x|sh|ch))$", @"$1es"},
            { "(.+)", @"$1s" }
        };

        public static string Pluralize(int count, string singular)
        {
            if (count == 1)
                return singular;

            if (Unpluralizables.Contains(singular))
                return singular;

            var plural = "";

            foreach (var pluralization in Pluralizations)
            {
                if (Regex.IsMatch(singular, pluralization.Key))
                {
                    plural = Regex.Replace(singular, pluralization.Key, pluralization.Value);
                    break;
                }
            }

            return plural;
        }
    }
}

And of course, some NUnit tests.

namespace AutomatedTests
{
    [TestFixture]
    public class FormattingTests
    {
        [Test]
        public void StandardPluralizationTests()
        {
            var dictionary = new Dictionary<string, string>();
            dictionary.Add("sausage", "sausages");  // Most words - Just add an 's'
            dictionary.Add("status", "statuses");   // Words that end in 's' - Add 'es'
            dictionary.Add("ax", "axes");           // Words that end in 'x' - Add 'es'
            dictionary.Add("octopus", "octopi");    // Some Words that end in 'us' - Replace 'us' with 'i'
            dictionary.Add("virus", "viri");        // Some Words that end in 'us' - Replace 'us' with 'i'
            dictionary.Add("crush", "crushes");     // Words that end in 'sh' - Add 'es'
            dictionary.Add("crutch", "crutches");   // Words that end in 'ch' - Add 'es'
            dictionary.Add("matrix", "matrices");   // Words that end in 'ix' - Replace with 'ices'
            dictionary.Add("index", "indices");     // Words that end in 'ex' - Replace with 'ices'
            dictionary.Add("mouse", "mice");        // Some Words that end in 'ouse' - Replace with 'ice'
            dictionary.Add("quiz", "quizzes");      // Words that end in 'z' - Add 'zes'
            dictionary.Add("mailman", "mailmen");   // Words that end in 'man' - Replace with 'men'
            dictionary.Add("man", "men");           // Words that end in 'man' - Replace with 'men'
            dictionary.Add("wolf", "wolves");       // Words that end in 'f' - Replace with 'ves'
            dictionary.Add("wife", "wives");        // Words that end in 'fe' - Replace with 'ves'
            dictionary.Add("day", "days");          // Words that end in '[vowel]y' - Replace with 'ys'
            dictionary.Add("sky", "skies");         // Words that end in '[consonant]y' - Replace with 'ies'

            foreach (var singular in dictionary.Keys)
            {
                var plural = dictionary[singular];

                Assert.AreEqual(plural, Formatting.Pluralize(2, singular));
                Assert.AreEqual(singular, Formatting.Pluralize(1, singular));
            }
        }

        [Test]
        public void IrregularPluralizationTests()
        {
            var dictionary = new Dictionary<string, string>();
            dictionary.Add("person", "people");
            dictionary.Add("child", "children");
            dictionary.Add("ox", "oxen");

            foreach (var singular in dictionary.Keys)
            {
                var plural = dictionary[singular];

                Assert.AreEqual(plural, Formatting.Pluralize(2, singular));
                Assert.AreEqual(singular, Formatting.Pluralize(1, singular));
            }
        }

        [Test]
        public void NonPluralizingPluralizationTests()
        {
            var nonPluralizingWords = new List<string> { "equipment", "information", "rice", "money", "species", "series", "fish", "sheep", "deer" };

            foreach (var word in nonPluralizingWords)
            {
                Assert.AreEqual(word, Formatting.Pluralize(2, word));
                Assert.AreEqual(word, Formatting.Pluralize(1, word));
            }
        }
    }
}

And finally, usage.

var output = Formatting.Pluralization(2, "item");
// Produces "items"
output = Formatting.Pluralization(5, "sheep");
// Produces "sheep"
output = Formatting.Pluralization(100, "sausage");
// Produces "sausages"
output = Formatting.Pluralization(1, "sausage");
// Produces "sausage"

Now, I’m sure that I’m missing some cases in there. For example, I haven’t found a good way to pluralize “proof.” If any of you wonderful people find another missing case, or if you want to add one, let me know in the comments.

Post

Google Maps Street View in Hamilton!

In Uncategorized on October 8, 2009 by Matt Grande

A couple days back, Google Maps Street View was finally added to Hamilton. Here’s some of my favourite images:

Actually, that’s all the neat stuff I’ve seen around Hamilton so far… Not that much, come to think of it.

In other news, I start a new job in just over a week. Things will be hectic for the next while, so I won’t be posting as much. And I don’t really post all that much to begin with so… Things will be really bad.

Post

Love vs. Hate

In Rails, lovestuffhatestuff.info on October 1, 2009 by Matt Grande

So, I created a website. Maybe you’d like to visit it? It’s just a quick little thing. You can see it here: lovestuffhatestuff.info