Results 1 to 7 of 7

Thread: C# StringBuilder Class Simulated in Javascript

  1. #1
    Join Date
    Nov 2006
    Posts
    3
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default C# StringBuilder Class Simulated in Javascript

    Title: StringBuilder Class
    Description: Simulates the C# StringBuilder Class in Javascript.
    Website: www.codevendor.com
    Author: Adam Smith
    Email: ibulwark@hotmail.com
    Date Created: November 12, 2006
    Zip file includes a compressed version, speed test and fully commented sourcecode.

    Attachment: Attachment 640

    Code:
    // Simulates the C# StringBuilder Class in Javascript.
    // Parameter["stringToAdd"] - The string to add. 
    StringBuilder = function(stringToAdd)
    {    
        var h = new Array();
        if(stringToAdd){h[0] = stringToAdd;} 
        this.Append = Append;
        this.AppendLine = AppendLine;
        this.ToString = ToString;
        this.Clear = Clear;
        this.Length = Length;
        this.Replace = Replace;
        this.Remove = Remove;
        this.Insert = Insert;
        this.GetType = GetType;      
        
        // Appends the string representation of a specified object to the end of this instance.
        // Parameter["stringToAppend"] - The string to append. 
        function Append(stringToAppend)
        {
            h[h.length] = stringToAppend;
        } 
    
        // Appends the string representation of a specified object to the end of this instance with a carriage return and line feed.
        // Parameter["stringToAppend"] - The string to append. 
        function AppendLine(stringToAppend)
        {
            h[h.length] = stringToAppend;
            h[h.length] = "\r\n";
        } 
      
        // Converts a StringBuilder to a String.
        function ToString()
        {
            if(!h){ return ""; }
            if(h.length<2){ return (h[0])?h[0]:""; }
            var a = h.join('');
            h = new Array();
            h[0] = a;
            return a;
        }
    
        // Clears the StringBuilder
        function Clear()
        {
            h = new Array();
        }
    
        // Gets the StringBuilder Length
        function Length()
        {
            if(!h){return 0;}
            if(h.length<2){ return (h[0])?h[0].length:0; }
            var a = h.join('');
            h = new Array();
            h[0] = a;
            return a.length;
        }
    
        // Replaces all occurrences of a specified character or string in this instance with another specified character or string.
        // Parameter["oldValue"] - The string to replace. 
        // Parameter["newValue"] - The string that replaces oldValue. 
        // Parameter["caseSensitive"] - True or false for case replace.
        // Return Value - A reference to this instance with all instances of oldValue replaced by newValue.
        function Replace(oldValue, newValue, caseSensitive)
        {
            var r = new RegExp(oldValue,(caseSensitive==true)?'g':'gi');
            var b = h.join('').replace(r, newValue);
            h = new Array();
            h[0] = b;
            return this;
        }
    
        // Removes the specified range of characters from this instance.
        // Parameter["startIndex"] - The position where removal begins. 
        // Parameter["length"] - The number of characters to remove.
        // Return Value - A reference to this instance after the excise operation has occurred.
        function Remove(startIndex, length)
        {       
            var s = h.join('');
    	    h = new Array();
    	
    	    if(startIndex<1){h[0]=s.substring(length, s.length);}
    	    if(startIndex>s.length){h[0]=s;}
    	    else
    	    {
    	        h[0]=s.substring(0, startIndex);  
    	        h[1]=s.substring(startIndex+length, s.length);
    	    }
    	
            return this;
        }
    
        // Inserts the string representation of a specified object into this instance at a specified character position.
        // Parameter["index"] - The position at which to insert.
        // Parameter["value"] - The string to insert. 
        // Return Value - A reference to this instance after the insert operation has occurred.
        function Insert(index, value)
        {
            var s = h.join('');
    	    h = new Array();
    	
    	    if(index<1){h[0]=value; h[1]=s;}
    	    if(index>=s.length){h[0]=s; h[1]=value;}
    	    else
    	    {
    	        h[0]=s.substring(0, index); 
    	        h[1]=value; 
    	        h[2]=s.substring(index, s.length);
    	    }
    	
            return this;
        }
    
        // Gets the type
        function GetType()
        {
            return "StringBuilder";
        }
    };

  2. #2
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Code:
        function Append(stringToAppend)
    Defining functions inside the constructor is inefficient, since they must be recreated every time the constructor is called. It's a much better idea to define them as properties of the prototype.
    Code:
            h[h.length] = "\r\n";
    Javascript in browsers uses \n for linebreaks, no matter the platform. Outside browsers, it would depend on the platform.
    Code:
    StringBuilder = function(stringToAdd)
    Interesting. Usually it's the custom to use the global-creating function identifier(params) syntax for the constructor, and an inline function definition for the function properties of the object. It's certainly bad style to omit the var keyword.
    function ToString()
    When Javascript converts to a string, it looks for the toString property. ToString will have no effect, since Javascript is case-sensitive. It's also probably a good idea to use the standard Java-like camel case convention.

    Insert looks interesting, but other than that, I can't see much of a use for this.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  3. #3
    Join Date
    Sep 2005
    Posts
    882
    Thanks
    0
    Thanked 3 Times in 3 Posts

    Default

    Quote Originally Posted by VectorX View Post
    Description: Simulates the C# StringBuilder Class in Javascript.
    I don't know what the StringBuilder Class is. It would be more useful if you could deescribe it
    Quote Originally Posted by Twey View Post
    It's also probably a good idea to use the standard Java-like camel case convention.
    What's Java-like came case convention?

  4. #4
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    What's Java-like came case convention?
    First letter lower-case, first letter of each subsequent word upper-case.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  5. #5
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by VectorX View Post
    Description: Simulates the C# StringBuilder Class in Javascript.
    Why would anyone want to do that?

    The reason why .NET and Java have StringBuilder classes is that instances of their respective String class are immutable. Any method or operator that would appear to alter the value in fact results in the creation of a completely new object, and that is inefficient. In ECMAScript, one would be working with string values, not objects.

    StringBuilder = function(stringToAdd)
    Why a function expression (and an undeclared variable, too), rather than a function declaration?

    this.Append = Append;
    this.AppendLine = AppendLine;
    this.ToString = ToString;
    this.Clear = Clear;
    this.Length = Length;
    this.Replace = Replace;
    this.Remove = Remove;
    this.Insert = Insert;
    Now you have it backwards: using function declarations, rather than function expressions.

    this.GetType = GetType;
    This should be added via the prototype object; the GetType method doesn't refer to any properties of the variable object, therefore it needn't be defined with that privilege.


    Quote Originally Posted by Twey View Post
    Defining functions inside the constructor is inefficient, since they must be recreated every time the constructor is called. It's a much better idea to define them as properties of the prototype.
    In general, yes, but most of those functions utilise local data - I highlighted the one that doesn't.


    Quote Originally Posted by blm126 View Post
    I don't know what the StringBuilder Class is. It would be more useful if you could deescribe it
    Internally, it contains a buffer that's used to efficiently modify a string. Taking concatenation as an example, rather than obtaining the values of two String objects, concatenating those values, then creating a new object to represent the result, the values are just added to the buffer.

    What's Java-like came case convention?
    A look at a Java style guide would provide more information, but essentially upper-case leading letters are reserved for class names (constructor functions, here), member names begin with a lower-case letter, and constants are all upper-case. "Words" within an identifier are capitalised, though in constants, they are separated with an underscore.

    Due to the syntactic similarities between Java and ECMAScript (and its derivatives), Java coding styles tend to spill over into scripting.

    Mike

  6. #6
    Join Date
    Jun 2005
    Location
    英国
    Posts
    11,876
    Thanks
    1
    Thanked 180 Times in 172 Posts
    Blog Entries
    2

    Default

    Quote Originally Posted by mwinter
    In general [creating functions within the constructor is inefficient], but most of those functions utilise local data - I highlighted the one that doesn't.
    That's not to say that they should, however. I would advocate making "h" a property of the object.
    Twey | I understand English | 日本語が分かります | mi jimpe fi le jbobau | mi esperanton komprenas | je comprends franšais | entiendo espa˝ol | t˘i Ýt hiểu tiếng Việt | ich verstehe ein bisschen Deutsch | beware XHTML | common coding mistakes | tutorials | various stuff | argh PHP!

  7. #7
    Join Date
    Dec 2004
    Location
    UK
    Posts
    2,358
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Quote Originally Posted by Twey View Post
    Quote Originally Posted by mwinter
    In general [creating functions within the constructor is inefficient], but most of those functions utilise local data...
    That's not to say that they should, however.
    No, of course. That is a value judgement, not a rule - one way or the other. The point is irrelevant here, though: don't use the code at all.

    If string concatenation performance is too low for a particular script (and MSIE doesn't perform well, in some cases), then use an array and concatenate it using the Array.prototype.join method. There's no need to go as far as the code posted here.

    Mike

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •