Roman numerals NSNumberFormatter?

  • Hello,

    I am probably missing something really obvious here (I usually am), but is there any easy way to convert an NSNumber (or just a regular int) to a roman numeral? NSNumberFormatter seemed the obvious place to look for this, but although it has everything else - including the very useful NSNumberFormatterSpellOutStyle - I can't see any style for converting to roman numerals.

    Does anybody know how to do this? Do I have to write my own formatter, am I missing one that exists, or is there an easier, more basic way of doing this that I am missing?

    Many thanks in advance,
    Keith
  • On 27 Oct 2006, at 14:28, Keith Blount wrote:

    > I am probably missing something really obvious here (I usually am),
    > but is there any easy way to convert an NSNumber (or just a regular
    > int) to a roman numeral? NSNumberFormatter seemed the obvious place
    > to look for this, but although it has everything else - including
    > the very useful NSNumberFormatterSpellOutStyle - I can't see any
    > style for converting to roman numerals.
    >
    > Does anybody know how to do this? Do I have to write my own
    > formatter, am I missing one that exists, or is there an easier,
    > more basic way of doing this that I am missing?

    Hi Keith,

    I don't know whether this is easy, or even a particularly good way to
    do it, but it certainly works for me:

    I set these two up when my program is loaded:
    NSDictionary  *romanNumeralPairs        = [[NSDictionary
    dictionaryWithContentsOfFile:[[NSBundle mainBundle]
    pathForResource:@"RomanNumerals" ofType:@"plist"]] retain];
    NSArray  *romanNumeralPairValues    = [[NSArray
    arrayWithObjects:@"1000", @"900", @"500", @"400", @"100", @"90",
    @"50", @"40", @"10", @"9", @"5", @"4", @"1", nil] retain];

    The file contents:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://
    www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>1</key>
    <string>i</string>
    <key>10</key>
    <string>x</string>
    <key>100</key>
    <string>c</string>
    <key>1000</key>
    <string>m</string>
    <key>4</key>
    <string>iv</string>
    <key>40</key>
    <string>xl</string>
    <key>400</key>
    <string>cd</string>
    <key>5</key>
    <string>v</string>
    <key>50</key>
    <string>l</string>
    <key>500</key>
    <string>d</string>
    <key>9</key>
    <string>ix</string>
    <key>90</key>
    <string>xc</string>
    <key>900</key>
    <string>cm</string>
    </dict>
    </plist>

    Then I can use them in this method...

    + (NSString *)convertArabicToRomanNumeralValue:(int)input
    {
    int    i, deflate = input;
    NSString  *romanValue = @"";
    NSDictionary *pairs = [[NSApp delegate] romanNumeralPairs];
    NSArray  *values = [[NSApp delegate] romanNumeralPairValues];
    int    itemCount = [a count], itemValue;

    for (i = 0; i < itemCount; i++) {
      itemValue = [[values objectAtIndex:i] intValue];

      while (deflate >= itemValue) {
      romanValue = [romanValue stringByAppendingString:[paris
    objectForKey:[values objectAtIndex:i]]];
      deflate -= itemValue;
      }
    }
    return romanValue;
    }

    ... and get back the desired string. It's easy to convert the result
    to uppercase if required.

    HPH,
    António

    -----------------------------------------
    Forgiveness is not an occasional act;
    it is a permanent attitude.

    --Martin Luther King, Jr
    -----------------------------------------
  • Fantastic! Thank you, that works perfectly for what I need. Because this will only be used only seldomly in my app, I just made an NSString category out of your code rather than store a .plist on file, which I've included below for the sake of the archives.

    Thanks very much for your help and for sharing your code,
    All the best,
    Keith

    @implementation NSString (RomanNumerals)

    + (NSString *)romanNumeralsFromInt:(int)input
    {
        int i, deflate = input;
        NSString *romanValue = @"";
        NSDictionary *pairs = [NSDictionary dictionaryWithObjectsAndKeys:
            @"i", @"1",
            @"x", @"10",
            @"c", @"100",
            @"m", @"1000",
            @"iv", @"4",
            @"xl", @"40",
            @"cd", @"400",
            @"v", @"5",
            @"l", @"50",
            @"d", @"500",
            @"ix", @"9",
            @"xc", @"90",
            @"cm", @"900",
            nil];

        NSArray *values = [NSArray arrayWithObjects:@"1000", @"900", @"500", @"400", @"100", @"90", @"50", @"40", @"10", @"9", @"5", @"4", @"1", nil];
        int itemCount = [values count], itemValue;

        for (i = 0; i < itemCount; i++)
        {
            itemValue = [[values objectAtIndex:i] intValue];

            while (deflate >= itemValue)
            {
                romanValue = [romanValue stringByAppendingString:[pairs objectForKey:[values objectAtIndex:i]]];
                deflate -= itemValue;
            }
        }

        return romanValue;
    }

    @end

    ----- Original Message ----
    From: Antonio Nunes <antonionunes...>
    To: Keith Blount <keithblount...>
    Cc: <cocoa-dev...>
    Sent: Friday, October 27, 2006 3:15:01 PM
    Subject: Re: Roman numerals NSNumberFormatter?

    On 27 Oct 2006, at 14:28, Keith Blount wrote:

    > I am probably missing something really obvious here (I usually am),
    > but is there any easy way to convert an NSNumber (or just a regular
    > int) to a roman numeral? NSNumberFormatter seemed the obvious place
    > to look for this, but although it has everything else - including
    > the very useful NSNumberFormatterSpellOutStyle - I can't see any
    > style for converting to roman numerals.
    >
    > Does anybody know how to do this? Do I have to write my own
    > formatter, am I missing one that exists, or is there an easier,
    > more basic way of doing this that I am missing?

    Hi Keith,

    I don't know whether this is easy, or even a particularly good way to
    do it, but it certainly works for me:

    I set these two up when my program is loaded:
    NSDictionary  *romanNumeralPairs        = [[NSDictionary
    dictionaryWithContentsOfFile:[[NSBundle mainBundle]
    pathForResource:@"RomanNumerals" ofType:@"plist"]] retain];
    NSArray  *romanNumeralPairValues    = [[NSArray
    arrayWithObjects:@"1000", @"900", @"500", @"400", @"100", @"90",
    @"50", @"40", @"10", @"9", @"5", @"4", @"1", nil] retain];

    The file contents:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://
    www.apple.com/DTDs/PropertyList-1.0.dtd";>
    <plist version="1.0">
    <dict>
        <key>1</key>
        <string>i</string>
        <key>10</key>
        <string>x</string>
        <key>100</key>
        <string>c</string>
        <key>1000</key>
        <string>m</string>
        <key>4</key>
        <string>iv</string>
        <key>40</key>
        <string>xl</string>
        <key>400</key>
        <string>cd</string>
        <key>5</key>
        <string>v</string>
        <key>50</key>
        <string>l</string>
        <key>500</key>
        <string>d</string>
        <key>9</key>
        <string>ix</string>
        <key>90</key>
        <string>xc</string>
        <key>900</key>
        <string>cm</string>
    </dict>
    </plist>

    Then I can use them in this method...

    + (NSString *)convertArabicToRomanNumeralValue:(int)input
    {
        int                i, deflate = input;
        NSString        *romanValue = @"";
        NSDictionary    *pairs = [[NSApp delegate] romanNumeralPairs];
        NSArray            *values = [[NSApp delegate] romanNumeralPairValues];
        int                itemCount = [a count], itemValue;

        for (i = 0; i < itemCount; i++) {
            itemValue = [[values objectAtIndex:i] intValue];

            while (deflate >= itemValue) {
                romanValue = [romanValue stringByAppendingString:[paris
    objectForKey:[values objectAtIndex:i]]];
                deflate -= itemValue;
            }
        }
        return romanValue;
    }

    ... and get back the desired string. It's easy to convert the result
    to uppercase if required.

    HPH,
    António

    -----------------------------------------
    Forgiveness is not an occasional act;
    it is a permanent attitude.

    --Martin Luther King, Jr
    -----------------------------------------
previous month october 2006 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today