Lamin Barrow
Lamin Barrow

Reputation: 879

Javascript: Parse array like search querystring

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

Upvotes: 0

Views: 288

Answers (3)

zs2020
zs2020

Reputation: 54514

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

Upvotes: 1

marcv
marcv

Reputation: 1976

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

}

Upvotes: 1

Paul S.
Paul S.

Reputation: 66304

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

Upvotes: 1

Related Questions