0

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

2
  • 1
    Can you provide the function you're actually using? Commented Jul 27, 2013 at 13:34
  • I have now added the parsing function to the question @LightStyle Commented Jul 27, 2013 at 13:46

3 Answers 3

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

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.
This is an elegant solution and its fast :). Thanks
1

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]];
    }

}

Comments

1

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.