Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Saturday, January 5, 2013

deep copy in javascript

One of the things about javascript I don't like is that there is not a simple way to copy an object literal so you don't have side effects when making updates to an object. this script show how I got around this. There is alos a fiddle as well which can be found here

Tuesday, September 18, 2012

Javascript string replacing

I spend a lot of time working in JavaScript.  I also find that I spend a lot of time replacing text in strings in this language.  Most of the time this can be done easily by using a good templating system. When you are working with localization systems, you can't rely on templating.

My first attempt at string replace was:
var stamp = function(template, tag, value){
    return template.replace('{'+ tag + '}', value);
};

This was a very simple attempt and wasn't very good.  It has a lot of problems. Top of the list is it will not get every instance of the tag in the string. You end up having to call stamp several times to replace the same thing.  So I set out to fix this problem.  I found you could use regular expressions to do this kind of thing.  I built out this simple function to do the work.
var stampValues = function (template, replacements) {
    for (var tag in replacements) {
        var reg = new RegExp('\{' + tag + '\}', 'g');
        template = template.replace(reg, replacements[tag]);
    }
    return template;
};

It's much better than the above one because it gets all the tags in the string. It's actually much better than any other code I have tried but more on that later.

The next version looked like this.  It uses underscore to do the flow control because each is better than "for" -- right?
var stampValuesEx0 = function (template, replacements) {
    _(replacements).each(function (value, tag) {
        var reg = new RegExp('\{' + tag + '\}', 'g');
        template = template.replace(reg, value);
    });
    return template;
};

It's not. It's slower.  Not noticeably slower but when you put a timer to it the stampValues is faster.

After looking at this I realized I was doing the Regular expression incorrectly. I could change the way I did it and probably get more speed out of it.  So I built this . . .
var stampValuesEx2 = function (template, replacements) {
    var setValues = (function () {
        var translateReg = /{\w+}/g;
        var cleanup = /[{}]/g;
        return function (s) {
            return (s.replace(translateReg, function (match) {
                return replacements[match.replace(cleanup, '')];
            }));
        };
    })();
    return setValues(template);
}

And It SUCKS.  It's slow; it takes double the time of the stampValues function.  There are a few things you can do to speed it up.  You can build out a closure with the regular expressions already in them this actually helped a lot. It cuts about 1/3 of the execution time.  That version looks like this:
var stampValuesEx3 = (function () {
    var translateReg = /{\w+}/g;
    var cleanup = /[{}]/g;
    return function (template, replacements) {
        return (template.replace(translateReg, function (match) {
            return replacements[match.replace(cleanup, '')];
        }));
    }
})();
It still not as fast as stampValues but it is faster than other attempts I have made.

In short I ended up using stampValues for my string replace function.

The code I used to test all these functions can be found at here take a look. If you have examples that you think are better or faster I would be interested in seeing them.


Thursday, March 22, 2012

String replace the better way.

This last week I have been working on making my team project at work run better on ie 7.  Usually that would mean that I spent all my time fixing styles, but there are better people then me at that.  So for me the project was getting rid of the scrpt is running two long errors.  The app I work on is very JavaScript heavy.  One of the worst offending functions I had found was the following:

function clean(word) {
        if (word) {
            
            return word.toLowerCase().
                replace(/\s/gi, "").                
                replace(/[àáâãäå]/gi, "a").
                replace(/æ/gi, "ae").
                replace(/ç/gi, "c").
                replace(/[èéêë]/gi, "e").
                replace(/[ìíîï]/gi, "i").
                replace(/ñ/gi, "n").
                replace(/[òóôõö]/gi, "o").
                replace(/œ/gi, "oe").
                replace(/[ùúûü]/gi, "u").
                replace(/[ýÿ]/gi, "y").
                replace(/\W/gi, "");
        } else {
            return word;
        }
    }

Which is a very brute force way of cleaning up strings for searching.  It was the most expensive call in our system.  With a little work it was changed to the following. 

var removeAccents = (function () {
        var translateReg = /[àáâãäåæçèéêëìíîïñòóôõöœùúûüýÿ]/g;
        var translate = {
            "à": "a", "á": "a", "â": "a", "ã": "a", "ä": "a",
            "å": "a", "æ": "ae", "ç": "ç", "è": "e", "é": "e",
            "ê": "e", "ë": "e", "ì": "i", "í": "i", "î": "i",
            "ï": "i", "ñ": "n", "ò": "o", "ó": "o", "ô": "o",
            "õ": "o", "ö": "o", "œ": "oe", "ù": "u", "ú": "u",
            "û": "u", "ü": "u", "ý": "y", "ÿ": "y"
        };
        return function(s) {
            return (s.replace(translateReg, function(match) {
                return translate[match];
            }));
        };
    })();
 
    function clean(word) {
        if (word) {
            return removeAccents(word.toLowerCase().replace(/\s/gi, "").replace(/\W/gi, ""));
        } else {
            return word;
        }
    }

For a massive boost in performance.




Wednesday, January 18, 2012

jQuery how I love you.

So I had a problem today where I needed to be able to tell if a JavaScript object was empty.  I spent 10 minuets  Googleing for a consice soluction then I went to jQuery util page on a whim and the answer was there.

http://api.jquery.com/jQuery.isEmptyObject/

With just one call the library will tell me if it has data.  Thanks to the people that build such cool tools for me to use.