Category Archives: string manipulation

2D Array to String

Actionscript:
  1. function format2D(a:Array):String {
  2.     var str:String="[";
  3.     for (var i:int = 0; i<a.length; i++) {
  4.         str+="["+a[i].toString()+"],";
  5.     }
  6.     str=str.substr(0,str.length-1);
  7.     str+="]";
  8.     return str;
  9. }
  10.  
  11. // test it out
  12. var array2D:Array = [[1,2,3], [4,5,6], [7,8,9]];
  13.  
  14. trace(array2D);
  15. trace(format2D(array2D));
  16.  
  17. /* outputs:
  18. 1,2,3,4,5,6,7,8,9
  19. [[1,2,3],[4,5,6],[7,8,9]]
  20.  
  21. */

When you trace a 2D array to the output window the actual structure of the array isn't clear. For some reason it just appears as a 1D array - this small function fixes that problem - it could also be used to save 2D arrays to text files etc...

Also posted in strings | Tagged , | Leave a comment

Object Parsing (object from string #2)

Actionscript:
  1. var str:String = '{numA:100, numB:100, stringA:"hi there", object:{red:155, green:155, blue: 255}, array1D:[1, 2, 3, 4, 5, "six"], array2D:[[1,0,0], [0,1,0], [0,0,"z"]], color:0xFF0000}'
  2.  
  3. var obj:Object = toObject(str);//, true); // comment the "true" in for some debug info
  4.  
  5. // acess every value in the object for testing purposes
  6. trace(obj.numA);
  7. trace(obj.numB);
  8. trace(obj.stringA);
  9. trace(obj.object.red, obj.object.green, obj.object.blue);
  10. trace(obj.array1D +" testing access: " + obj.array1D[3]);
  11. trace(obj.array2D + " testing access: " + obj.array2D[1] + "  -  " + obj.array2D[2][2]);
  12. trace(obj.color);
  13.  
  14. /*outputs:
  15. 100
  16. 100
  17. hi there
  18. 155 155 255
  19. 1,2,3,4,5,six testing access: 4
  20. 1,0,0,0,1,0,0,0,z testing access: 0,1,0  -  z
  21. 16711680
  22. */
  23.  
  24. function toObject(str:String, debug:Boolean=false):Object{
  25.     var cmds:Array = new Array();
  26.     var stack:String = "";
  27.     // skip first {
  28.     str = str.replace(/^\s+\{|^\{/, "");
  29.     var obj:Object = new Object();
  30.     for (var i:int = 0; i<str.length; i++){
  31.         var char:String = str.charAt(i);
  32.         if (char == ":"){
  33.             cmds.push(["name:", stack])
  34.             stack = "";
  35.             char = "";
  36.         }else
  37.         if (char == "," || char == "}"){
  38.             if (stack != ""){
  39.               cmds.push(["value:", stack]);
  40.             }
  41.             stack = "";
  42.             char = "";
  43.         }else
  44.         if (char == '"'){
  45.             stack = '"';
  46.             for (j = i + 1; j <str.length; j++){
  47.                 char = str.charAt(j);
  48.                 stack+=char;
  49.                 i++;
  50.                 if (char == '"'){
  51.                      break;
  52.                 }
  53.             }
  54.             cmds.push(["value:", stack]);
  55.             stack = "";
  56.             char = "";
  57.         }else
  58.         if (char == "{"){
  59.             cmds.push(["object:", stack]);
  60.             for (var j:int = i; j <str.length; j++){
  61.                 char = str.charAt(j);
  62.                 stack+=char;
  63.                 i++;
  64.                 if (char == "}"){
  65.                      break;
  66.                 }
  67.             }
  68.             cmds.push(["value:", stack]);
  69.             stack = "";
  70.             char = "";
  71.         }else
  72.         if (char == "["){
  73.             cmds.push(["array:", stack]);
  74.             stack = "";
  75.             char = "";
  76.         }else if (char == "]"){
  77.             if (stack != ""){
  78.                 cmds.push(["value:", stack]);
  79.             }
  80.             stack = "";
  81.             char = "";
  82.             i++;
  83.         }
  84.         stack += char;
  85.     }
  86.     // show some debug info
  87.     if (debug){
  88.         for (i = 0; i<cmds.length; i++) trace(cmds[i]);
  89.     }
  90.     // build the object
  91.     var prop:String;
  92.     var arrayMode:Boolean = false;
  93.     var nest:int = 0;
  94.     for (i = 0; i<cmds.length; i++){
  95.         if (cmds[i][0] == "name:"){
  96.             prop = cmds[i][1].replace(/\s/g, "");
  97.             arrayMode = false;
  98.             nest = 0;
  99.         }else if (cmds[i][0] == "value:"){
  100.             if (arrayMode == false){
  101.               obj[prop] = valueType(cmds[i][1]);
  102.             }else{
  103.                 // populate array
  104.                 if (nest == 1){
  105.                   obj[prop].push(valueType(cmds[i][1]))
  106.                 }else{
  107.                   obj[prop][nest - 2].push(valueType(cmds[i][1]))
  108.                 }
  109.             }
  110.         }else if (cmds[i][0] == "object:"){
  111.             i++;
  112.             obj[prop] = toObject(cmds[i][1], debug);
  113.         }else if (cmds[i][0] == "array:"){
  114.             arrayMode = true;
  115.             nest++;
  116.             if (nest == 1){
  117.                 // create array
  118.                 obj[prop] = new Array()
  119.             }else{
  120.                 // nested array
  121.                 obj[prop].push(new Array());
  122.             }
  123.         }
  124.     }
  125.     return obj;
  126. }
  127.  
  128. function valueType(val:*):* {
  129.     if (isNaN(Number(val))) {
  130.            // remove leading and trailing white
  131.            // remove "" around strings
  132.            val = val.replace(/^s+|s+$/g,"").replace(/^"|"$/g,"");
  133.            //  see if it's a boolean
  134.            if (val == "true"){
  135.                val = true;
  136.            }else if (val == "false"){
  137.                val = false
  138.            }
  139.     } else {
  140.         val = Number(val);
  141.     }
  142.     return val;
  143. }

This rather large code snippet parses ActionScript style Object syntax. While this is by no means a complete parser - it was easy to write and saved me a great deal of time on a project recently....

I specifically needed support for 1D and 2D arrays as Object properties. If that weren't the case I would have used something simple like yesterdays method. The array support won't work with anything higher than a 2D array (for now... may fix that soon). For fun I also added nested Object support - this doesn't have any dimensional limitation so you can nest as many objects as you want. For instance.. this works just fine:

Actionscript:
  1. var gameUser:Object = toObject('{name:"Mr.S", alive:true, stats:{lives:100, points:1200, data:[100,12,40,12,90], plant:{branch:{leaves:["red, "green", "blue"]}}}');
  2.  
  3. trace(gameUser.stats.plant.branch.leaves[0]);
  4. trace(gameUser.stats.lives);
  5. // boolean support
  6. trace("not true is false: ", !gameUser.alive);
  7. /*outputs:
  8. red
  9. 100
  10. not true is false:  false
  11. */

You'll also notice the added boolean support in the above example. Which was suggested by katopz in the comments of yesterdays post.

Definitely need to add a word of warning here... I wouldn't be surprised if there were a bug or two lurking in this code. The Objects I've been parsing with it are all quite similar... so use at your own risk.

UPDATEs - Known Issues:
1) fixed a bug where if a String property contains a ,{}[] or : character the parser failed.

Also posted in dynamic, strings | Tagged , | 4 Comments

Object from String

Actionscript:
  1. var str:String='{x: 10, y:10, width:100, heigth:100, name:"myClip", type:"clip"}';
  2.  
  3. var obj:Object=toObject(str);
  4.  
  5. trace(obj.x + obj.width, obj.name, obj.type);
  6.  
  7. function toObject(str:String):Object {
  8.     str=str.replace(/\{|\}/g,"");
  9.     // to an array of name value pairs [0] = name, [1] = value etc...
  10.     var pairs:Array=str.split(/\:|\,\s+/);
  11.     var obj:Object = new Object();
  12.     for (var i:int = 0; i<pairs.length; i+=2) {
  13.         obj[pairs[i]]=numOrString(pairs[i+1]);
  14.     }
  15.     return obj;
  16. }
  17. function numOrString(val:*):* {
  18.     if (isNaN(Number(val))) {
  19.         if (val.charAt(0) == '"' && val.charAt(val.length - 1) == '"'){
  20.             val = val.substr(1, val.length - 2);
  21.         }
  22.     } else {
  23.         val=Number(val);
  24.     }
  25.     return val;
  26. }

A very limited way to parse an object from a string... Tomorrow I'll post a better version of this that's a good deal more complex and doesn't really use regular expressions... This works nicely if you don't have arrays as Object properties...

Also posted in dynamic, strings | Tagged , | 2 Comments

Formating Numbers with Commas

Actionscript:
  1. trace(formatNum(1000));
  2. trace(formatNum(10000000));
  3. trace(formatNum(1000000.39485));
  4.  
  5. function formatNum(num:Number):String {
  6.     var newStr:String = "";
  7.     var str:String = num.toString();
  8.    
  9.     var parts:Array = str.split(".");
  10.     str = parts[0];
  11.     var end:String = (parts[1]) ? "." + parts[1] : "";
  12.    
  13.     var i:int = str.length;
  14.     while(i--> 0){
  15.          var char:String = str.charAt(i);
  16.          if ((str.length - i) % 3 == 0){
  17.             newStr = "," + char +newStr;
  18.          }else{
  19.             newStr = char +  newStr;
  20.          }
  21.     }
  22.     return newStr + end;
  23. }
  24. /*
  25. outputs:
  26. 1,000
  27. 10,000,000
  28. 1,000,000.39485
  29. */

The function formatNum() returns a string given a number argument ... it adds commas where appropriate and takes into account decimal values. This is useful anywhere you need to display numbers over 1,000, in a game, in a calculator app etc...

Posted in string manipulation | Tagged , | Leave a comment

String.indexOf()

Actionscript:
  1. var words:String = "one two three four five";
  2.  
  3. trace("two: ", words.indexOf("two"));
  4.  
  5. var letters:String = "abcd";
  6.  
  7. trace("d: ",letters.indexOf("d"));
  8.  
  9. trace("z: ",letters.indexOf("z"));
  10.  
  11. /*
  12. outputs:
  13. two:  4
  14. d:  3
  15. z:  -1
  16. */

indexOf() searches a string for another string and returns an index... in line 3 above, I search the words string for the smaller string "two" and indexOf() gives me the index of the letter "t". If indexOf() doesn't find anything it will return -1 (as in the case of line 9).

I seem to recall using this in some unexpected places. I'll see if I can dig up an example over the next few days.

Also posted in strings | Tagged , | Leave a comment

Zig Zag Binary ix2 & i/2

Actionscript:
  1. var txt:TextField = TextField(addChild(new TextField()));
  2. txt.text = "";
  3. txt.width = 190;
  4. txt.height = 400;
  5. txt.multiline = true;
  6.  
  7. var count:int = 1;
  8. function render():void{
  9.     var line = int(count).toString(2);
  10.     while(line.length <31){
  11.         line = "0" + line;
  12.     }
  13.     txt.appendText(line + "\n");
  14.     txt.scrollV= txt.maxScrollV;
  15. }
  16.  
  17. addEventListener(Event.ENTER_FRAME, onCountUp);
  18. function onCountUp(evt:Event):void {
  19.     count *= 2;
  20.     render();
  21.     if (count ==0x40000000){
  22.         removeEventListener(Event.ENTER_FRAME, onCountUp);
  23.         addEventListener(Event.ENTER_FRAME, onCountDown);
  24.     }
  25. }
  26. function onCountDown(evt:Event):void {
  27.     count /= 2;
  28.     render();
  29.     if (count ==1){
  30.         addEventListener(Event.ENTER_FRAME, onCountUp);
  31.         removeEventListener(Event.ENTER_FRAME, onCountDown);
  32.     }
  33. }

The above animates a zig zag pattern in a TextField.

Also posted in Math, strings | Leave a comment

N to the power of N (with strings)

Actionscript:
  1. var input:String =  "a, b, c";
  2.  
  3. var words:Array = input.split(", ");
  4. var max:String = "";
  5. var maxD:String =  (words.length - 1).toString();
  6. for (var i:int = 0; i<words.length; i++){
  7.     max += maxD;
  8. }
  9. var maxInt:int = parseInt(max,words.length);
  10.  
  11. for(i = 0; i<=maxInt; i++){
  12.      var indices:String = i.toString(words.length);
  13.      var r:String = "";
  14.      var k:int=0;
  15.      for (var j:int = 0; j<indices.length; j++){
  16.          r += words[parseInt(indices.charAt(j))] +" ";
  17.          k++;
  18.      }
  19.      while(k <words.length) {
  20.         r = words[0] +" "+ r;
  21.         k++;
  22.      }
  23.     trace(r);
  24. }
  25. trace(i, " variations");

Like many things on this site, I coded this rather quickly and it can probably be cleaned up...

Setting the input variable of the above snippet to "a, b" will output:

a a
a b
b a
b b
4 variations

Setting the input to "a, b, c" will output:

a a a
a a b
a a c
a b a
a b b
a b c
a c a
a c b
a c c
b a a
b a b
b a c
b b a
b b b
b b c
b c a
b c b
b c c
c a a
c a b
c a c
c b a
c b b
c b c
c c a
c c b
c c c
27 variations

I created this to work with words... inputs like "bread, breath, blobs, backwards". Be careful because you can quickly get millions of outputs:

1 to the power of 1 is 1
2 to the power of 2 is 4
3 to the power of 3 is 27
4 to the power of 4 is 256
5 to the power of 5 is 3125
6 to the power of 6 is 46,656
7 to the power of 7 is 823,543
8 to the power of 8 is 16,777,216
etc...

Also posted in Math, misc | Tagged , | Leave a comment

MYSQL SOUNDEX

C:
  1. SELECT * FROM _users WHERE SOUNDEX(name) LIKE SOUNDEX('jon');

Not ActionScript, but the coolest thing I've seen in Mysql in awhile, the soundex function will convert a string into a soundex index... read more about it on wikipedia.

I did some tests and it matches things like:

what's your name? & whats yer name

very cool... since this isn't ActionScript, I will post another snippet right after this.

UPDATE: Actually started reading more about this stuff and dug up some algorithms... metaphone etc... fun stuff, maybe I'll port some of it to actionscript...

Also posted in misc, strings | Leave a comment

split() hacks & RegExp

Actionscript:
  1. var path:String = "section/home.swf";
  2.  
  3. var deepLinkValue:String = path.split("/")[1].split(".swf")[0];
  4.  
  5. trace(deepLinkValue);
  6. /*outputs:
  7. home
  8. */

As a primarily self taught programmer there was a time when I didn't know what a regular expression was. There was also a time when ActionScript didn't have them (you had to use a library). Sometimes when I'm in a rush I still do weird things like the above instead of regular expressions... pretty nasty I know.

Here are two different regular expressions that do the same thing:

Actionscript:
  1. var path = "section/home.swf"
  2.  
  3. trace(path.match(/\w+(?=\.)/))
  4. /*outputs:
  5. home
  6. */
  7.  
  8. trace(path.replace(/.+\/|\..+/g, ""))
  9. /* also outputs:
  10. home
  11. */

Actually, I'd be curious to see other regular expressions that only return one value (not an array) that achieve this same thing... feel free to post of a comment if you can think of one...

Also posted in strings | Tagged , | Leave a comment

substr() Remove First Character

Actionscript:
  1. var someString:String = "_file";
  2. trace(someString.substr(1));
  3. /*
  4. ouptuts:
  5. file
  6. */

Turns out the second argument of substr() is optional..... not sure how I never noticed that before.

Also posted in strings | Tagged , | Leave a comment