Tuesday, May 26, 2009

Sorting string characters alphabetically

In Java if you want to sort the characters in a String alphabetically it is very easy:
String test = "sorting";
char[] chars = test.toCharArray();
Arrays.sort(chars);
System.out.println(new String(chars))// prints out "ginorst"

But how can we do this in Flex/ActionScript? Perhaps there is an easier way than this, but here are my utility functions that sorts the characters in a String by putting each character into an array, sorting the array, then joining the array back into a String.
/**
 * Converts the string's characters into an array.
 @param string the string to convert into an array
 @param unique if true then only unique characters are added to the array
 @param ignoreCase only applies if the unique property is set to true
 */
public static function toCharArray(string:String, unique:Boolean = false
       ignoreCase:Boolean = false):Array {
    var array:Array = new Array();
    if ((string != null&& (string.length > 0)) {
        // for tracking unique letters
        var seen:Object = new Object();
        // add each character to the array
        for (var i:int = 0; i < string.length; i++) {
            var char:String = string.charAt(i);
            if (unique) {
                // unique characters only, possibly ignoring case 
                // use the character code as the key (could just use the letter too) 
                var key:String = (ignoreCase ? char.toUpperCase() : char);
                key = key.charCodeAt(0).toString(10);
                if (!seen.hasOwnProperty(key)) {
                    seen[keytrue;
                    array.push(char);
                }
            else {
                array.push(char);
            }
        }
    }
    return array;
}

/**
 * Sorts the characters in the string alphabetically. 
 @param ignoreCase if false (default) upper case letters come first then lowercase
 @param descending if true then the String is sorted in reverse
 @param unique if true then only unique characters are sorted and returned
 */
public static function sort(string:String, ignoreCase:Boolean = false
            descending:Boolean = false, unique:Boolean = false):String {
    // no point in sorting
    if ((string == null|| (string.length <= 1)) {
        return string;
    }
    var chars:Array = toCharArray(string, unique, ignoreCase);
    var options:uint = 0;
    if (ignoreCase) {
        options = options | Array.CASEINSENSITIVE;
    }
    if (descending) {
        options = options | Array.DESCENDING;
    }
    chars.sort(function(s1:String, s2:String):int {
        return ObjectUtil.stringCompare(s1, s2, ignoreCase);
    }, options);
    
    var sorted:String = chars.join("");
    return sorted;
}

Feel free to comment if you know of a simpler way to sort characters in a String.

No comments: