Steveo
Steveo

Reputation: 147

Generate a query string from a jQuery array with multiple values for a query var

I wrote the following code which takes an array and converts it into a filter string, the string gets generated but instead of

product_size=123&product_size=456

I want this to be product_size=123+456.

I suspect I need to check if the array key for product_size already exists and then push the second number into it, then generate the filter string.

I have created a keysAlreadyUsed array but I can't figure out how to do this.

Maybe I am over thinking this and some form of string manipulation would suffice.

 // Array

    arrayTest = [];
    arrayTest.push( ['product_size', 123] );
    arrayTest.push( ['product_size', 456] );
    arrayTest.push( ['product_color', 123] );

    // Start filter string and array of keys already used

    filterString = '';
    keysAlreadyUsed = [];

    // Loop the array test

    $.each( arrayTest, function( index1, value1 ) {

    	// If the key has already been set
      
      if( jQuery.inArray( value1[0], keysAlreadyUsed ) ) {
      
      	// Push into the existing array key

      } else {
      
      	// New array we can loop through later with the product_size and the 123, 456 in it.

      }
      
      // Populate filter string
      
      filterString += value1[0] + '=' + value1[1] + '&';
      
      // Push the key already used into the keys already used array
      
      keysAlreadyUsed.push( value1[0] );

    });

    // Output

    console.log(filterString);
    console.log(keysAlreadyUsed);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

jsFiddle: https://jsfiddle.net/6oxc8umz/2/

Upvotes: 2

Views: 200

Answers (2)

Tyler Roper
Tyler Roper

Reputation: 21672

First I'd turn the array into an object so you can associate the key to the concatenated values. Because you're using jQuery, you can utilize $.param to format it as you need to.

const arrayTest = [['product_size', 123],['product_size', 456],['product_color', 123]];

const toFilterString = obj => decodeURIComponent($.param(obj));

let params = arrayTest.reduce((output, [key,value]) => {
  if (output[key]) output[key] += `+${value}`;       //if key exists, concatenate value
  else (output[key]) = value;                        //else, set value
  return output;
}, {});
  
console.log(toFilterString(params));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

If you need the value to be URL-encoded, you can remove decodeURIComponent(...).

Upvotes: 2

Ele
Ele

Reputation: 33736

Maybe is not the most efficient.

The first call of function reduce for creating a key-value object and the second call for generating the queryString.

let arrayTest = [['product_size', 123], ['product_size', 456] ,['product_color', 123]],
    result = Object.entries(arrayTest.reduce((a, [key, value]) => {
      if (a[key]) a[key] += `+${String(value)}`;
      else a[key] = value;
      return a;
    }, Object.create(null))).reduce((a, [key, value]) => a + `${key}=${value}&`, "").slice(0, -1);

console.log(result);

Upvotes: 2

Related Questions