Ask Ben: Splitting Strings In Javascript To Form New Variables
Posted December 19, 2008 at 2:53 PM by Ben Nadel
I have a variable (string) with a value of: "foobar|http://www.myurl.com". From that, I want to make two new variables:
label: foobar
url: http://www.myurl.com
How do I split it?
Before we can answer this, we have to think about where variables live. Variables in any programming language always reside within some sort of a scope. Sometimes this scope has a label (as in "window") and sometimes this scope has no label (as in the local scope of a function). In order for us to be able to create new variables dynamically, we are going to need a reference to the scope in which they will be created.
In Javascript, if you do not specify a variables scope, it defaults to "window" - the global scope. That being said, creating a new variable, most of the time, is the exact same as creating a new key in an object. For example, when creating a global Javascript variable:
- var objData = {};
... is essentially the same as this:
- window[ "objData" ] = {};
Notice that our variable name, "objData", is nothing more than a key with in the "window" object (global scope).
Sound good? Now, let's look at a demo. In the following code, I am abstracting this idea out into a method, SetVariables(), that takes care of scoping the new variables for you:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html>
- <head>
- <title>Splitting Strings Into Variables</title>
-
- <script type="text/javascript">
-
- // This will take a string that is formatted as a delimited
- // list of values and store those values into the given
- // variable names in the given container.
- function SetVariables(
- strList, // The list of values.
- arrLabels, // The array of new variable names.
- strDelimiter, // OPTIONAL - defaults to "|".
- objContainer // OPTIONAL - defaults to "window".
- ){
-
- // Check to see if there is a defined container.
- // If not then default the container to window.
- // This is basically where any "unscoped" variable
- // resides naturally.
- if (!objContainer){
- objContainer = window;
- }
-
- // Check to see if a delmiter was passed. If not,
- // then define a default one.
- if (!strDelimiter){
- strDelimiter = "|";
- }
-
- // Now that we have our values defaults, we are
- // going to split the string into an array using
- // the given delimiter. Escape the delimiter in case
- // it's a special regEx value.
- var arrValues = strList.split(
- new RegExp( ("\\" + strDelimiter), "gi" )
- );
-
- // Loop over the values and assign them to the
- // labels passed in. Do this in order. In the loop
- // conidition, make sure that we stay in bounds for
- // both the value array and the variable name array.
- for (
- var i = 0 ;
- (
- (i < arrValues.length) &&
- (i < arrLabels.length)
- );
- i++
- ){
-
- // Store the new value in the container
- objContainer[ arrLabels[ i ] ] = arrValues[ i ];
-
- }
-
- // No need to pass back container as it is an object
- // and will be passed by reference; but, let's just
- // pass it back for good measure.
- return( objContainer );
- }
-
- </script>
- </head>
- <body>
-
- <h1>
- Splitting Strings Into Variables
- </h1>
-
- <!--- Let's do some testing. --->
- <script type="text/javascript">
-
- // For the first test, we are going to use the default
- // delimiter and the default container (window).
- SetVariables(
- "4|Naomi|Sexy",
- [ "ID", "Name", "Description" ]
- );
-
- // Now, let's output those values.
- document.write( "Window Test:<br />" );
- document.write( "ID: " + ID + "<br />" );
- document.write( "Name: " + Name + "<br />" );
- document.write( "Description: " + Description + "<br />" );
- document.write( "<br />" );
-
-
- // Now, let's test this using a custom container. Since
- // the container is the fourth argument, we HAVE to
- // define the delimiter as well.
- var objTest = {};
-
- SetVariables(
- "4|Naomi|Sexy",
- [ "ID", "Name", "Description" ],
- "|",
- objTest
- );
-
- // Now, let's output those values.
- document.write( "Custom Container Test:<br />" );
- document.write( "ID: " + objTest.ID + "<br />" );
- document.write( "Name: " + objTest.Name + "<br />" );
- document.write( "Description: " + objTest.Description + "<br />" );
- document.write( "<br />" );
-
- </script>
-
- </body>
- </html>
In the demo, we are testing the SetVariables() first with the default behavior and then with a custom delimiter and container. When we run this code, we get:
Splitting Strings Into Variables
Window Test:
ID: 4
Name: Naomi
Description: Sexy
Custom Container Test:
ID: 4
Name: Naomi
Description: Sexy
Notice that the variables were dynamically set and then accessed successfully in both scope environments. Remember, the trick here is to remember that a variable cannot exist on its own - it can only exist as the element of given scope.
I hope that helps.
Reader Comments
Normally I think your posts are right on Ben, sometimes a little verbose, but I respect that you're trying teach people instead of just answering their question. This one might be a case of going a little overboard.
Writing a function to split out a string with two keys (based on the pipe delimiter) just comes across as excessive, and not that helpful IMO to the OP.
@Andy,
Totally valid point. There was actually a second-half to this conversation which talked about converting the above functionality into a jQuery plug-in. So, first, I wanted to discuss the abstraction of the idea (above) and then probably follow it up with a post on the jQuery plug-in.
But yeah, this is a bit wordy :)
var urlData = "foobar|http://www.myurl.com";
var urlStruct = {"label": urlData.split("|")[0], "url": urlData.split("|")[1]};
If you assign the split to a variable first, you'll save yourself a small amount of processing, avoiding the split twice:
var urlData = "foobar|http://www.myurl.com".split("|");
var urlStruct = {"label": urlData[0], "url": urlData[1]};



