Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2 : Iterating and upper/lower case some characters

I want to modify a Swift string by converting some characters to uppercase, some others to lowercase.

In Obj-c I had following :

- (NSString*) lowercaseDestination:(NSString*) string {
    NSUInteger length = string.length;
    unichar buf[length+1];
    [string getCharacters:buf];

    BOOL up = true;
    for (int i=0; i< length ; i++) {
        unichar chr = buf[i];

        if( .... ) {
            buf[i] = toupper(chr);
        } else {
            buf[i] = tolower(chr);
        }
    }
    string = [NSString stringWithCharacters:buf length:length];
    return string;

How would you do that in Swift 2 ?

I did no find any Character method to upper or lower the case.

Would be an array of String of 1 character be an option ? (And then use String methods to upper and lower each String

like image 453
Matthieu Riegler Avatar asked Aug 07 '15 06:08

Matthieu Riegler


1 Answers

String has a upperCaseString method, but Character doesn't. The reason is that in exotic languages like German, converting a single character to upper case can result in multiple characters:

print("ß".uppercaseString) // "SS"

The toupper/tolower functions are not Unicode-safe and not available in Swift.

So you can enumerate the string characters, convert each character to a string, convert that to upper/lowercase, and concatenate the results:

func lowercaseDestination(str : String) -> String {
    var result = ""
    for c in str.characters {
        let s = String(c)
        if condition {
            result += s.lowercaseString
        } else {
            result += s.uppercaseString
        }
    }
    return result
}

which can be written more compactly as

func lowercaseDestination(str : String) -> String {
    return "".join(str.characters.map { c -> String in
        let s = String(c)
        return condition ? s.lowercaseString : s.uppercaseString
    })
}

Re your comment: If the condition needs to check more than one character then you might want to create an array of all characters first:

func lowercaseDestination(str : String) -> String {

    var result = ""
    let characters = Array(str.characters)
    for i in 0 ..< characters.count {
        let s = String(characters[i])
        if condition {
            result += s.lowercaseString
        } else {
            result += s.uppercaseString
        }
    }
    return result
}
like image 138
Martin R Avatar answered Oct 17 '22 23:10

Martin R