0

Folks, using js libraries such as underscore,underscore.string, or lodash, I'd like to convert the following String to an Object

'animals=cat&dogs&horses&fish=salmon&tuna';

The following are constant: animals and fish. Separator is =

The result should look like:

{
    animals: 'cats&dogs&horses',
    fish: 'salmon&tona'
}

animals and fish can occur in the string in any order.

Thanks!

PS Its not a duplicate of Parse query string in JavaScript... as the requirements are to return an object for later parsing...

Community
  • 1
  • 1
Cmag
  • 12,570
  • 23
  • 75
  • 129
  • 1
    this is a duplicate. see here : http://stackoverflow.com/questions/2090551/parse-query-string-in-javascript – David Haim Mar 26 '15 at 17:04
  • and btw , in Javascript Strings ARE objects. correct title would be : convert query into a key-value object – David Haim Mar 26 '15 at 17:06
  • @david, great hunch, but i really need to escape `&` hence using `request._parsedUrl.query` instead of `request.query`. Thanks ! So how can i get the result im looking for? :) – Cmag Mar 26 '15 at 17:08
  • dud you look in the link? – David Haim Mar 26 '15 at 17:11
  • absolutely, i am not trying to parse a request in this method. its a helper function which literally needs to do what i've asked – Cmag Mar 26 '15 at 17:12
  • ok , so put an example which reflect your need. what you posted is clearly a url-query – David Haim Mar 26 '15 at 17:13
  • ok, imagine you need to escape '&' using _.escape and you'll be stuck – Cmag Mar 26 '15 at 17:14
  • so just use _.unescape and continue from there like the link suggest – David Haim Mar 26 '15 at 17:15
  • This is a malformed query string. However, or whoever, or wherever it came from, the `&` needs to be encoded for it be parsable. –  Mar 26 '15 at 17:19
  • 1
    @torazaburo, query string is correct in my case, hence me posting the question. I really would like someone to answer the question instead of linking to other questions on stackoverflow :) – Cmag Mar 26 '15 at 17:21
  • Why not use regex capture groups to find what you want? – evolutionxbox Mar 26 '15 at 17:23
  • @torazaburo unfortunately i can not change the clients calling the api to encode the & :) so back to the original question... – Cmag Mar 26 '15 at 17:23
  • @evolutionxbox how :) example? – Cmag Mar 26 '15 at 17:23
  • I just tried... unless you escape the "&" like this, `animals=cat%26dogs%26horses&fish=salmon%26tuna`. You cannot parse this string and separate the values into what you want, url or not. – evolutionxbox Mar 26 '15 at 17:28
  • @Cmag As it stands, the string is unparseable and ambiguous. You can not spin gold out of straw. There is a bug in the program generating this string, which needs to get fixed. –  Mar 26 '15 at 17:59

2 Answers2

0

Quick vanilla js solution:

function parseQuery (string) {
  var result = {}, components, i, firstPair, current;
  components = string.split("&");

  for (i = 0; i < components.length; i++) {
    if (components[i].indexOf("=") !== -1) {
      if (typeof current !== "undefined") {
        result[current] = result[current].join("&");
      }
      firstPair = components[i].split("=");
      current = firstPair[0];
      result[current] = [firstPair[1]];
    } else {
      result[current].push(components[i]);
    }
  }

  result[current] = result[current].join("&");

  return result;
}
Andrew Larson
  • 453
  • 2
  • 7
  • But this won't give the desired results, because the ampersands are used inside the values themselves and for separating the values. – evolutionxbox Mar 26 '15 at 17:31
  • It works on the sample and should work on any other of the pattern :`key=val&val&key=val&val`. Components with keys are distinguished by checking whether they contain `=`; this gets around the ambiguity of the ampersands. – Andrew Larson Mar 26 '15 at 17:38
0

This is a bit more compact:

var x = 'animals=cat&dogs&horses&fish=salmon&tuna';

Split the string using the feature of split which preserves splitters which are groups in the splitting regexp. We split on anything which starts at the beginning of the string or with a &, and contains an = at the end:

var pieces = x.split(/((?:^|&)\w+=)/) . filter(Boolean);
>> ["animals=", "cat&dogs&horses", "&fish=", "salmon&tuna"]

The result will be an array of interspersed keynames and values. Process this into an object:

var result = {};
for (var i=0; i<pieces.length; i+=2) { 
    result[pieces[i].replace(/^&|=$/g, '')] = pieces[i+1];
}