Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

This is a string i have in my javascript

var searchString = City=20&Region=67&&Interests[8]=8&Interests[13]=13&Interests[4]=4&Duration[1]=Full+Day+Tour&Duration[3]=Evening+Tour&Duration[5]=2+Day+Short+Break&Departs[Fri]=Fri&Departs[Sat]=Sat&Departs[Sun]=Sun&TourLanguages=1&action_doSearch=Update 

and i have a function

function loadDataFrom(request){

        //if request if empty then return
        if(request == "") 
            return;

        var request = decodeURIComponent(request);

        //if we get there then its likely we have a search query to process
        var searchCriteria = request.split('&');
        var hash = {};

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

            //we can safely ignore the "view" and 'action_doSearch' becuase they are not searched on
            if(unescape(val[0]) === 'view' || unescape(val[0]) === 'action_doSearch')
                continue;

            //filter objects without any values
            if(val[1] != '')
                //add the names and values to our object hash
                hash[unescape(val[0])] = unescape(val[1]);

        }


        //iterate over the hash objects and apply the current selection 
        $.each(hash, function(index, value) {
            switch (index) {
                case 'City':
                case 'Region':
                case 'TourLanguages':
                  //do stuff;
                    break;

                case 'Duration[]':
                case 'Departs[]':
                    //do something esle


                default:
                    break;

            }           
        });
    };

that parses the URL parameters into an objecct hash with the following values.

City: "20"
Region: "67"
Departs[Fri]: "Fri"
Departs[Sat]: "Sat"
Departs[Sun]: "Sun"
Duration[1]: "Full+Day+Tour"
Duration[3]: "Evening+Tour"
Duration[5]: "2+Day+Short+Break"
Interests[4]: "4"
Interests[8]: "8"
Interests[13]: "13"
TourLanguages: "1"

but what i'd really like to do is to seperate the url into array like values like so

City: "20"
Region: "67"
Departs: ["Fri","Sat","Sun"]
Duration: ["Full+Day+Tour", "Evening+Tour", "2+Day+Short+Break"]
Interests: ["4", "8", "13"]
TourLanguages: "1"

Any help/pointers on this problem is greatly appreciated. Thanks in Advance

share|improve this question
1  
Can you provide the function you're actually using? –  LightStyle Jul 27 '13 at 13:34
    
I have now added the parsing function to the question @LightStyle –  Lamin Barrow Jul 27 '13 at 13:46

3 Answers 3

up vote 1 down vote accepted

For something like this, to make it easier on myself I would write a RegExp to get the parts, then do some if logic to decide how to construct the Object.

var searchString = "City=20&Region=67&&Interests[8]=8&Interests[13]=13&Interests[4]=4&Duration[1]=Full+Day+Tour&Duration[3]=Evening+Tour&Duration[5]=2+Day+Short+Break&Departs[Fri]=Fri&Departs[Sat]=Sat&Departs[Sun]=Sun&TourLanguages=1&action_doSearch=Update",
    o = {};

('&' + searchString)
    .replace(
        /&([^\[=&]+)(\[[^\]]*\])?(?:=([^&]*))?/g,
        function (m, $1, $2, $3) {
            if ($2) {
                if (!o[$1]) o[$1] = [];
                o[$1].push($3);
            } else o[$1] = $3;
        }
    );

o; /*
{
    "City": "20",
    "Region": "67",
    "Interests": ["8", "13", "4"],
    "Duration": ["Full+Day+Tour", "Evening+Tour", "2+Day+Short+Break"],
    "Departs": ["Fri", "Sat", "Sun"],
    "TourLanguages": "1",
    "action_doSearch": "Update"
} */

RegEx RegExp Graph Graphic

share|improve this answer
    
I have just added my current parsing function to my question above. I'll try to put your changes on and see how it works. –  Lamin Barrow Jul 27 '13 at 13:48
    
This is an elegant solution and its fast :). Thanks –  Lamin Barrow Jul 27 '13 at 16:35

I would do it this way:

var str = 'City=20&Region=67&&Interests[8]=8&Interests[13]=13&Interests[4]=4&Duration[1]=Full+Day+Tour&Duration[3]=Evening+Tour&Duration[5]=2+Day+Short+Break&Departs[Fri]=Fri&Departs[Sat]=Sat&Departs[Sun]=Sun&TourLanguages=1&action_doSearch=Update',
    strsplit = str.split(/&+/),
    o = {};

for (var i = 0, l = strsplit.length; i < l; i++) {

    var r = strsplit[i].match(/^([^=\[\]]+)(?:\[[^\]]+\])?=(.*)$/);

    if (o[r[1]] === undefined) {
        o[r[1]] = r[2];
    } else if (o[r[1]].push) {
        o[r[1]].push(r[2]);
    } else {
        o[r[1]] = [o[r[1]], r[2]];
    }

}
share|improve this answer

This is a perfect scenario to use Map-Reduce and I recommend you to use underscore.js to implement something simple, elegant and more readable solution.

var m = _.map(searchString.split('&'), function (item) {
    var parts = item.split('='), names = parts[0].split('[');
    return [names[0], parts[1]];
});

var result = _.reduce(m, function(memo, item){
    var key = item[0], value = item[1];
    if(memo[key] === undefined) memo[key] = [value]
    else memo[key].push(value)
    return memo;
}, {});

console.log(result);
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.