tags:

views:

50

answers:

3

I'm not a javascript guru. I've got the following code below:

var aCookieValues = sCookieContentString.split('&'); // split out each set of key/value pairs
var aCookieNameValuePairs = aCookieValues.split('='); // return an array of each key/value

What I'm trying to do is split the first string via & and then create another array that takes the first array and splits it further via the = character that exists in every value in the aCookieValues array

I get the error aCookieValues.split is not a function.

I've seen an example that basically does the same thing but the second time this guy is using a loop:

(http://seattlesoftware.wordpress.com/2008/01/16/javascript-query-string/)

    // '&' seperates key/value pairs
    var pairs = querystring.split("&");

    // Load the key/values of the return collection  
    for (var i = 0; i < pairs.length; i++) {
        var keyValuePair = pairs[i].split("=");
        queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
    }

Ultimately what I'm trying to achieve here is a final dictionary with key/value pairs based off the '=' split. I'm simply trying to split up a cookie's values and shove it into a nice dictionary so I can then get certain values out of that dictionary later on.

+1  A: 

You are getting this error because aCookieValues is an array, and it does not have a split method. You would need to call the split method on each element of aCookieValues:

var aCookieValues = sCookieContentString.split('&');

for (var i = 0; i < aCookieValues.length; i++) {
   var aCookieNameValuePairs = aCookieValues[i].split('=');

   // Handle aCookieNameValuePairs[0] as the key
   // Handle aCookieNameValuePairs[1] as the value
}

To shove everything in your nice dictionary, simply declare it before the for loop: var myDict = {}, and then put the following after the split('=') call:

myDict[aCookieNameValuePairs[0]] = aCookieNameValuePairs[1];

EDIT: Which, after reading your question properly, is the same method used in the code snippet you supplied. I hope at least this explains how that works :)

Daniel Vassallo
I'm just wondering how not to do this with a loop the second time.
CoffeeAddict
this is the line I don't get. myDict[aCookieNameValuePairs[0]] = aCookieNameValuePairs[1]; And I did not know there are JavaScript dictionaries after trying to look it up...there isn't looks like but I just found a nice article finally http://www.4guysfromrolla.com/webtech/100800-1.shtml
CoffeeAddict
You have to use a loop. Actually you could use [`map()`](https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map), but that's quite advanced, and is just a shorthand for looping through all the elements of the array. (And it does not work in all browsers).
Daniel Vassallo
@coffeeaddict: JavaScript dictionaries are really straightforward. Your declare one: `var myDict = {};`... Then you simply do `myDict['myKey'] = 'someValue';`... You can then call `alert(myDict['myKey'])` and you'd be alerted `someValue`... That part you quoted is basically doing the same thing, since `aCookieNameValuePairs[0]` is just a string with the key of each element of `aCookieValues`, and `aCookieNameValuePairs[1]` is the value.
Daniel Vassallo
@coffeeaddict: I suggest checking out the section "Objects" at: http://www.crockford.com/javascript/survey.html... Note that ` = new Object()` and ` = {}` are the same thing. The latter is just a shorthand notation, called the "object literal".
Daniel Vassallo
Thanks Daniel. Will check that out now. I'm just used to static languages...so this is a bit of a pain for me.
CoffeeAddict
coffeeaddict: Don't worry. Once you get used to them, I bet you won't go back to static languages :)
Daniel Vassallo
Danial, ok so that article says: var myHashtable = {};This statement makes a new hashtable and assigns it to a new local variable but you are saying that {} just creates an object right? There is no concept of a hashtable object or is there?
CoffeeAddict
@coffeeaddict: Continue reading a bit more until you reach the part that says: **"JavaScript takes this much farther: objects and hashtables are the same thing"** :) ... That's why I said in another comment to your question that "Everything is a dictionary in JavaScript". Because everything is an object, and objects are just hashtables :) It may sound funny, but that turns out to be very useful!
Daniel Vassallo
... BTW, you may want to install Firebug in Firefox or use the JavaScript Console in Chrome to try these out in a JavaScript REPL shell.
Daniel Vassallo
I've got firebug and have been using it for years. and I do use the javascript console which is how I see this error.
CoffeeAddict
Thanks Daniel, this helped a lot, did not find links as good as you showed here yet when researching on the net.
CoffeeAddict
@coffeeaddict: That's great! :)
Daniel Vassallo
@coffeeaddict: If you like video lectures, and you have a couple of hours to spare, I suggest checking out the first four at: http://www.catonmat.net/blog/learning-javascript-programming-language-through-video-lectures. They're really good at introducing concepts such as these. They are given by Douglas Crockford, which is very authoritative in the subject (the same author of the link I provided).
Daniel Vassallo
Thanks much!! Appreciate all the advice here.
CoffeeAddict
+1  A: 

split operates on a string. You're trying to split aCookieValues, which is an array. The example you cite is looping through the array, and then splitting each element as a string.

Just for fun, one way to deal with this would be to use a map function, which performs an action on each element of an array, and emits an array as a result. If you make a generic map function available to all your arrays, like this:

if (!Array.prototype.map) { // don't step on anyone's toes
  Array.prototype.map = function( f ) {
    var result = [];
    var aLen = this.length;
    for( x = 0 ; x < aLen ; x++ ) {
      result.push( f(this[x]) );
    }
    return result; 
  };
};

...you can call it as a method on your array directly. Thus:

​yourstring = 'x=3&y=4&zed=blah&something=nothing';
dictionary = yourstring.split('&').map( function(a){ return a.split('='); } );

dictionary will now be a nice clean array of (arrays of) name/value pairs, like this:

[["x", "3"], ["y", "4"], ["zed", "blahblah"], ["something", "nothing"]]

If your use case becomes complex, an approach like this can be a nice abstraction. Of course, you can arrange these data in other structures if needed, either by playing with a function passed into map, or processing in a separate pass.

Ken Redler
thanks, I'm not that advanced in JS yet..did not know of maps.
CoffeeAddict
I don't understand how the passed in function with the x param works..is that basically some kind of delegate?
CoffeeAddict
The map function above is defined as taking argument `f`. In the body of `map`, we see that the `f` argument is a function, which is called inside the `for` loop -- `f(this[x])`. The argument passed in is `this[x]` -- meaning, the current element of the original array in question. Think of the `function(a)` code (I changed it to `a` for clarity) as a sort of template -- a general form of the function we want to pass to `map`. When the function is actually applied inside `map`, we're just saying "take the actual argument, and slot it in wherever we had `a` in that "template".
Ken Redler
I don't think map() is (yet?) standard. You can't rely on its presence or uniform behavior across implementations of js. I'm defining a basic version here, but it would probably be smart to check for it first. I'll add that to the answer.
Ken Redler
cool I will definitely look into that moving forward as a valuable approach. I need to digest it first.
CoffeeAddict
+1  A: 

In your second line you are attempting to call split() on an array, when it is a function defined on strings.

Example:

"a=1&b=2&c=3".split('&') returns an array ['a=1','b=2','c=3']

Your code would then call split on the array:

['a=1','b=2','c=3'].split('=')

But that function doesn't exist. It seems like your goal is to split each string in the array, so the example you gave in the question seems appropriate - loop through each element and split it.

fd
thanks...I see that now.
CoffeeAddict