3/20/2007

Javascript string replacing function

In python there's a very convinient string replacing function that comes with every string. The following example show how it works:

To construct a string:   "firstname:Runsun, lastname:Pan, project:wysiwyc"

firstname='Runsun'
lastname ='Pan'
project ='wysiwyc'
s= 'firstname:<b>%s</b>, lastname:<b>%s</b>, project:<b>%s</b>'%(firstname, lastname, project)

The symbol % attaching to the end of a string is a function to insert a series of strings (firstname, lastname, project) into the original string. This not only makes it easier to read but also easier to type, as compared to:

'firstname:<b>'+ firstname +'</b>, lastname:<b>'+ lastname+ '</b>, project:<b>'+ project + '</b>'

In javascript you don't have that luxury. I came up with a tiny function that does just that:

function ___(s)
{
var ss = arguments[0].split('___')
var out= [ss[0]]
for (var i=1;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join('')
}

So now you can do this:

s= ___('firstname:<b>___</b>, lastname:<b>___</b>, project:<b>___</b>',firstname, lastname, project)

I found that this syntax is actually better than its python cousin, because the symbol "___" implies that there's something to be filled, just like what we used to do when filling up a form with a pen.

It would look even more clear if we attach this "___()" function to the string prototype:

String.prototype._= function()
{

var ss = this.valueOf().split('___')
var out= [ss.shift()]
for (var i=0;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join('')
}

which allows this:

s= 'firstname:<b>___</b>, lastname:<b>___</b>, project:<b>___</b>'._(firstname, lastname, project)

Some other uses of this function:

Example-1:

alert('myArray=[___]'._(myArray))

Example-2:

tag = '<___ style="___">___</___>'
DIV = tag._('div','___','___','div')
SPAN = tag._('span','___','___','span')
adiv = DIV._("border:1px dashed blue; color:blue", "div example")
aspan= SPAN._("color:red;background-color:yellow", "span example")

The 2nd example gives:

div example
span example

Replace with a data in a hash


The above ___() function is already very helpful. But the original python % has one other feature:

data= {'fname':'Runsun'
,'lname':'Pan'
,'proj' :'wysiwyc'}
s= 'firstname:<b>%(fname)s</b>, lastname:<b>%(lname)s</b>, project:<b>%(proj)s</b>'%(data)

By inserting a (fname) into %s, you allow the data be in hash form. Now lets put this feature into the ___() function.

Stand-alone ___() function:

function ___(s)
{
var isObj=false
try {
isObj = arguments[1].constructor.toString().split('(')[0].split(' ')[1]=='Object'
}catch(e) {}

if (isObj)
{
var args = arguments[1]
for (var k in args) { s=s.split( '_'+k+'_').join( args[k] ) }
return s

}else{

var ss = arguments[0].split('___')
var out= [ss[0]]
for (var i=1;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join("")
}
}

Attached to string prototype:

String.prototype._= function()
{
var ss= this.valueOf()
var isObj=false
try {
isObj = arguments[0].constructor.toString().split('(')[0].split(' ')[1]=='Object'
}catch(e) {}

if (isObj)
{
var args = arguments[0]
for (var k in args) { ss=ss.split( '_'+k+'_').join( args[k] ) }
return ss

}else{

var ss = ss.split('___')
var out= [ss.shift()]
for (var i=0;i<ss.length;i++){
out.push(arguments[i])
out.push(ss[i])
}
return out.join("")
}
}

Now we can do this in javascript:

data= {fname:'Runsun'
,lname:'Pan'
,proj :'wysiwyc'}
s= 'firstname:<b>_fname_</b>, lastname:<b>_lname_</b>, project:<b>_proj_</b>'._(data)

Again, IMO, this looks better than its python cousin does.

UPDATE(7/23/07): See a regular expression version of the same function.

No comments: