Why this array permutation(duplicate) does not work - javascript

var permuteUnique = function(nums) {
var res = [];
if (nums.length == 0 || nums == null) return res;
var used = [];
var list = [];
nums.sort();
dfs(nums, used, list, res);
return res;
};
function dfs(nums, used, list, res) {
if (list.length == nums.length) {
res.push(list.slice());
return;
}
console.log(res, list);
for (var i = 0; i < nums.length; i++) {
if (used[i]) continue;
if (i > 0 && nums[i] === nums[i - 1] && !used[i]) continue;
used[i] = true;
list.push(nums[i]);
dfs(nums, used, list.slice(), res);
used[i] = false;
list.pop();
}
}
console.log(permuteUnique([1,1,2]));
after running,
when input is [1,1,2]. the result always returns []. The correct answer should be [[1,1,2],[1,2,1],[2,1,1]].
Can someone help have a look at? Thank you in advance.

To begin with: you are not reassigning the variable res in the function permuteUnique.
var permuteUnique = function(nums) {
var res = []; // var res is assigned
if (nums.length == 0 || nums == null) return res;
var used = [];
var list = [];
nums.sort();
dfs(nums, used, list, res);
return res; // you never reassigned res, so it remains []
};
The result of permuteUnique(whateverArgumentYouPass) will, regardless of the passed argument, always be []. You might want to read more about the basics of functions and return values here.
Besides, inside permuteUnique you call dfs(nums, used, list, res); but you never capture the return value. If you do the computations for finding the permutations there, you should return the computed values and assign it to a variable (in this case res). This would also not work in your code, because your function dfs will always return undefined.
There are also a couple of other things not working, but I'd first focus on above-mentioned points.

Related

how to make _.includes method

I am a junior developer who has been coding for 4 weeks.
I'm working on a JavaScript method.
I'll show you the code I used first.
_.each = function (collection, iteratee) {
if(Array.isArray(collection)===true){
for(let i=0;i<collection.length;i++){
iteratee(collection[i],i,collection)
}
}else{
let objvalues= Object.values(collection)
let objkeys = Object.keys(collection)
for(let i=0;i<objvalues.length;i++){
iteratee(objvalues[i],objkeys[i],collection)
}
}
};
_.includes = function (arr, target) {
let result
_.each(arr, function(a){
if(a === target)
result = true
if (a !== target)
result = false
})
return result;
};
It's a condition.
If the _.include method matches the value found by the element in the array, the true must be returned.
If the element in the array does not match the value you are looking for, you must return false.
I made the _include method.
If the element in the array does not match the value you are looking for, the return to false is successful.ten thousand
If the element in the array matches the value you are looking for, you must return true
This is where you fail.
It seems that the ture cannot be returned and only false is returned.
How should I handle this?
The problem is here:
_.each(arr, function(a){
if(a === target)
result = true
if (a !== target)
result = false
})
You reassign result on every iteration. As a result, the only iteration that matters for the final value of result is the last iteration.
Instead, initialize result to false, and reassign to true when the target is found:
const _ = {};
_.each = function(collection, iteratee) {
if (Array.isArray(collection) === true) {
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection)
}
} else {
let objvalues = Object.values(collection)
let objkeys = Object.keys(collection)
for (let i = 0; i < objvalues.length; i++) {
iteratee(objvalues[i], objkeys[i], collection)
}
}
};
_.includes = function(arr, target) {
let result = false;
_.each(arr, function(a) {
if (a === target)
result = true
})
return result;
};
console.log(
_.includes([1, 2, 3], 2)
);
It'd be cleaner to break the loop once a match is found, but your _each isn't set up for that:
const _ = {};
_.each = function(collection, iteratee) {
if (Array.isArray(collection) === true) {
for (let i = 0; i < collection.length; i++) {
iteratee(collection[i], i, collection)
}
} else {
let objvalues = Object.values(collection)
let objkeys = Object.keys(collection)
for (let i = 0; i < objvalues.length; i++) {
iteratee(objvalues[i], objkeys[i], collection)
}
}
};
_.includes = function(arr, target) {
for (const a of arr) {
if (a === target)
return true
}
return false;
};
console.log(
_.includes([1, 2, 3], 2)
);
In addition to what CertainPerfomance already said, you could see how Array.includes was implemented to get an inspiration, here is the specifications from TC39.

Check If Linked List is Palindrome in JavaScript

I have written the following function in JavaScript to check if a singly Linked List is a palindrome. However, I'm failing 2 out of 10 tests, and I can't figure out why.
Here are the tests I'm falling.
l: [0, 1, 0]
l: [1, 1000000000, -1000000000, -1000000000, 1000000000, 1]
Both should return true for the palindrome, but my function is returning false.
Here's my code:
function isListPalindrome(l) {
let curr = l;
let arr = [];
if (l == null)
return true;
// push all elements of l into the stack.
// a stack in JS is an array.
while(curr != null){
arr.push(l.value);
// move ahead:
curr = curr.next;
}
let curr2 = l;
// Traverse the list again & check by popping from the stack:
while(curr2 != null){
// get the top most element on the stack:
let num = arr.shift();
// check if the node data isn't the same as the element popped:
if (curr2.value != num){
return false;
}
// move ahead:
curr2 = curr2.next;
}
return true;
}
Thank you!
Inside the first while loop you're pushing l.value but l is not being incremented so it's pushing the same value to arr.
You now have arr which is suppose to be l in reverse. In the second while loop, instead of using arr.shift() use arr.pop(). This will take the first element off the arr stack. Remember that a stack is first in, last out.
Notice also that when you're comparing the list front to back you'll reach a point of irrelevancy, the half way point. Once you know that half the values in the forward list are the same as the values in the reverse list you know the rest will pass the test.
Here's what it's suppose to look like. You should try to figure out how to do odds yourself.
function isListPalindrome(l) {
let curr = l;
let arr = [];
if (l == null)
return true;
// push all elements of l into the stack.
// a stack in JS is an array.
while(curr != null){
arr.push(curr.value);
// move ahead:
curr = curr.next;
}
let curr2 = l;
let length = arr.length;
// Traverse the list again & check by popping from the stack:
while(curr2 != null){
// get the top most element on the stack:
let lastNum = arr.pop();
// check if the node data isn't the same as the element popped:
if (curr2.value != lastNum){
return false;
}
// Half way point for evens
if (length / 2 === arr.length) {
return true;
}
// move ahead:
curr2 = curr2.next;
}
return true;
}
solving with pushing values to an array and then check if the array is palindromic will have S:O(N). with reversing the second half and then traversing will have S:O(1). T:O(N) is same for both:
var isPalindrome = function (head) {
let fast_pointer = head;
let slow_pointer = head;
// when fast_ppointer reaches to the tail, slow_pointer will be in the middle
while (fast_pointer && fast_pointer.next) {
fast_pointer = fast_pointer.next.next;
slow_pointer = slow_pointer.next;
}
// now, slow_pointer is in the middle and we reverse from slow_pointer till the head
let prev = null;
while (slow_pointer) {
// slow_pointer=slow_pointer.next how we iterate in linked lists.
// so make sure we keep a reference to the next iteration
temp = slow_pointer.next;
slow_pointer.next = prev;
prev = slow_pointer;
slow_pointer = temp;
}
let left = head;
let right = prev;
while (right) {
if (left.val !== right.val) {
return false;
}
left = left.next;
right = right.next;
}
return true;
};
var isPalindrome = function (head) {
let values = [];
while (head) {
values.push(head.val);
head = head.next;
}
let rev = [];
head.map((e) => {
rev.unshift(e);
});
if (values.every((val, index) => val === rev[index])) {
return true;
} else {
return false;
}
};
class Node {
constructor(value, next = null) {
this.value = value;
this.next = next;
}
}
const is_palindromic_linked_list = function (head) {
let front = head;
const traverse = (node) => {
if (!node) return true;
//reverse the LL
const reverse = traverse(node.next);
//check value if they are equal
const valChecker = front.value == node.value;
front = front.next;
return reverse && valChecker;
}
return traverse(head)
};
head = new Node(2)
head.next = new Node(4)
head.next.next = new Node(6)
head.next.next.next = new Node(4)
head.next.next.next.next = new Node(2)
console.log(`Is palindrome: ${is_palindromic_linked_list(head)}`)
head.next.next.next.next.next = new Node(2)
console.log(`Is palindrome: ${is_palindromic_linked_list(head)}`)
I push all the elements of the list in an array and then I convert the array with join function to a string so that i can compare if the string is the same as the inverse using reverse function if it is then it is a palindrome
function isListPalindrome(l) {
if(l === null) return true;
let array =[];
let current = l;
while (current != null){
array.push(current.value);
current = current.next
}
if(array.join('')=== array.reverse().join('')) return true;
return false
}

Extract array of objects based on their content

In JavaScript I have a JSON array like this:
var r = [{"name":"a","bool":false},{"name":"b","bool":false},
{"name":"c","bool":false},{"name":"a","bool":false},
{"name":"b","bool":false},{"name":"c","bool":true},
{"name":"a","bool":true}];
I want to build another array containing all the objects where name=="a" and bool==false. I solved this by looping, but I wanted to know if there is another way to do it.
How can I do?
[edit]
My loop was:
var rLen = r.length;
var newArray = [];
for(var i=0;i<rLen;i++) {
if(r[i].name=="a"&&r[i].bool==false) {
newArray.push(r[i]);
}
}
In the end it will always be solved by loops internally, e.g.
var r = [{"name":"a","bool":false},{"name":"b","bool":false},
{"name":"c","bool":false},{"name":"a","bool":false},
{"name":"b","bool":false},{"name":"c","bool":true},
{"name":"a","bool":true}];
var result = r.filter(function(item){
return item.name === 'a' && !item.bool;
});
If you look at the polyfill, you'll notice the loop:
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun/*, thisArg*/) {
'use strict';
if (this === void 0 || this === null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (typeof fun !== 'function') {
throw new TypeError();
}
var res = [];
var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
for (var i = 0; i < len; i++) { // <--
if (i in t) {
var val = t[i];
// NOTE: Technically this should Object.defineProperty at
// the next index, as push can be affected by
// properties on Object.prototype and Array.prototype.
// But that method's new, and collisions should be
// rare, so use the more-compatible alternative.
if (fun.call(thisArg, val, i, t)) {
res.push(val);
}
}
}
return res;
};
}
Since you're interested in performance, here is a jsperf comparing the two: http://jsperf.com/aarontgrogg-array-filter-vs-for-loop
may be
var r1 = r.filter(function(item){ return item.name === "a" && !item.bool; });

Nest JSON from array

I am trying to achieve something which seemed very basic but is getting me mad over the last days.
I have a simple array : ["a","b","c","d","e"] and I want to turn it into a nested JSON like this:
{"a":{"b":{"c":{"d":{"e":""}}}}}
Looping over it, I ran in problems like "how do you save the last key to set it afterwards without erasing it" and so on.
Does anyone has an idea?
You might have had problems because you were looping in the wrong direction. Try to build the object from inside-out:
array.reduceRight(function(v, key) {
var o = {};
o[key] = v;
return o;
}, "")
or, with a loop:
var val = "";
for (var i=array.length; i--; )
var o = {};
o[array[i]] = val;
val = o;
}
return val;
Here's one way to do it, recursively:
function convertToNestedObject(arr) {
var result = {};
if (arr.length === 1) {
result[arr[0]] = '';
} else {
result[arr[0]] = convertToNestedObject(arr.slice(1, arr.length));
}
return result;
}
You could pass the start index in to the function instead of using slice and creating copies of the array:
function convertToNestedObject(arr, startIndex) {
var result = {};
if (arr.length - startIndex === 1) {
result[arr[startIndex]] = '';
} else {
result[arr[startIndex]] = convertToNestedObject(arr, startIndex + 1);
}
return result;
}
Example: http://jsfiddle.net/jwcxfaeb/1/
Put current element as key and empty object ({}) as value. Continue with newly inserted empty object.
function toNested(arr){
var nested = {};
var temp = nested;
for(var i=0; i<arr.length; i++){
temp[arr[i]] = {};
temp = temp[arr[i]];
}
return nested;
}

The $.param( ) inverse function in JavaScript / jQuery

Given the following form:
<form>
<input name="foo" value="bar">
<input name="hello" value="hello world">
</form>
I can use the $.param( .. ) construct to serialize the form:
$.param( $('form input') )
=> foo=bar&hello=hello+world
How can I deserialize the above String with JavaScript and get a hash back?
For example,
$.magicFunction("foo=bar&hello=hello+world")
=> {'foo' : 'bar', 'hello' : 'hello world'}
Reference: jQuery.param( obj ).
You should use jQuery BBQ's deparam function. It's well-tested and documented.
This is a slightly modified version of a function I wrote a while ago to do something similar.
var QueryStringToHash = function QueryStringToHash (query) {
var query_string = {};
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
pair[0] = decodeURIComponent(pair[0]);
pair[1] = decodeURIComponent(pair[1]);
// If first entry with this name
if (typeof query_string[pair[0]] === "undefined") {
query_string[pair[0]] = pair[1];
// If second entry with this name
} else if (typeof query_string[pair[0]] === "string") {
var arr = [ query_string[pair[0]], pair[1] ];
query_string[pair[0]] = arr;
// If third or later entry with this name
} else {
query_string[pair[0]].push(pair[1]);
}
}
return query_string;
};
How about this short functional approach?
function parseParams(str) {
return str.split('&').reduce(function (params, param) {
var paramSplit = param.split('=').map(function (value) {
return decodeURIComponent(value.replace(/\+/g, ' '));
});
params[paramSplit[0]] = paramSplit[1];
return params;
}, {});
}
Example:
parseParams("this=is&just=an&example") // Object {this: "is", just: "an", example: undefined}
My answer:
function(query){
var setValue = function(root, path, value){
if(path.length > 1){
var dir = path.shift();
if( typeof root[dir] == 'undefined' ){
root[dir] = path[0] == '' ? [] : {};
}
arguments.callee(root[dir], path, value);
}else{
if( root instanceof Array ){
root.push(value);
}else{
root[path] = value;
}
}
};
var nvp = query.split('&');
var data = {};
for( var i = 0 ; i < nvp.length ; i++ ){
var pair = nvp[i].split('=');
var name = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair[1]);
var path = name.match(/(^[^\[]+)(\[.*\]$)?/);
var first = path[1];
if(path[2]){
//case of 'array[level1]' || 'array[level1][level2]'
path = path[2].match(/(?=\[(.*)\]$)/)[1].split('][')
}else{
//case of 'name'
path = [];
}
path.unshift(first);
setValue(data, path, value);
}
return data;
}
I am using David Dorward's answer, and realized that it doesn't behave like PHP or Ruby on Rails how they parse the params:
1) a variable is only an array if it ends with [], such as ?choice[]=1&choice[]=12, not when it is ?a=1&a=2
2) when mulitple params exist with the same name, the later ones replaces the earlier ones, as on PHP servers (Ruby on Rails keep the first one and ignore the later ones), such as ?a=1&b=2&a=3
So modifying David's version, I have:
function QueryStringToHash(query) {
if (query == '') return null;
var hash = {};
var vars = query.split("&");
for (var i = 0; i < vars.length; i++) {
var pair = vars[i].split("=");
var k = decodeURIComponent(pair[0]);
var v = decodeURIComponent(pair[1]);
// If it is the first entry with this name
if (typeof hash[k] === "undefined") {
if (k.substr(k.length-2) != '[]') // not end with []. cannot use negative index as IE doesn't understand it
hash[k] = v;
else
hash[k.substr(0, k.length-2)] = [v];
// If subsequent entry with this name and not array
} else if (typeof hash[k] === "string") {
hash[k] = v; // replace it
// If subsequent entry with this name and is array
} else {
hash[k.substr(0, k.length-2)].push(v);
}
}
return hash;
};
which is tested fairly thoroughly.
I know this is an old thread, but maybe there is still some relevance in it?
Inspired by Jacky Li's good solution I tried a slight variation of my own with the objective to also be able to take care of arbitrary combinations of arrays and objects as input. I looked at how PHP would have done it and tried to get something "similar" going. Here is my code:
function getargs(str){
var ret={};
function build(urlnam,urlval,obj){ // extend the return object ...
var i,k,o=obj, x, rx=/\[([^\]]*)\]/g, idx=[urlnam.replace(rx,'')];
while (x=rx.exec(urlnam)) idx.push(x[1]);
while(true){
k=idx.shift();
if(k.trim()=='') {// key is empty: autoincremented index
if (o.constructor.name=='Array') k=o.length; // for Array
else if (o===obj ) {k=null} // for first level property name
else {k=-1; // for Object
for(i in o) if (+i>k) k=+i;
k++;
}
}
if(idx.length) {
// set up an array if the next key (idx[0]) appears to be
// numeric or empty, otherwise set up an object:
if (o[k]==null || typeof o[k]!='object') o[k]=isNaN(idx[0])?{}:[];
o=o[k]; // move on to the next level
}
else { // OK, time to store the urlval in its chosen place ...
// console.log('key',k,'val',urlval);
o[k]=urlval===""?null:urlval; break; // ... and leave the while loop.
}
}
return obj;
}
// ncnvt: is a flag that governs the conversion of
// numeric strings into numbers
var ncnvt=true,i,k,p,v,argarr=[],
ar=(str||window.location.search.substring(1)).split("&"),
l=ar.length;
for (i=0;i<l;i++) {if (ar[i]==="") continue;
p=ar[i].split("=");k=decodeURIComponent(p[0]);
v=p[1];v=(v!=null)?decodeURIComponent(v.replace(/\+/g,'%20')):'';
if (ncnvt && v.trim()>"" && !isNaN(v)) v-=0;
argarr.push([k,v]); // array: key-value-pairs of all arguments
}
for (i=0,l=argarr.length;i<l;i++) build(argarr[i][0],argarr[i][1],ret);
return ret;
}
If the function is called without the str-argument it will assume window.location.search.slice(1) as input.
Some examples:
['a=1&a=2', // 1
'x[y][0][z][]=1', // 2
'hello=[%22world%22]&world=hello', // 3
'a=1&a=2&&b&c=3&d=&=e&', // 4
'fld[2][]=2&fld[][]=3&fld[3][]=4&fld[]=bb&fld[]=cc', // 5
$.param({a:[[1,2],[3,4],{aa:'one',bb:'two'},[5,6]]}), // 6
'a[]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13',// 7
'a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13'// 8
].map(function(v){return JSON.stringify(getargs(v));}).join('\n')
results in
{"a":2} // 1
{"x":{"y":[{"z":[1]}]}} // 2
{"hello":"[\"world\"]","world":"hello"} // 3
{"a":2,"b":null,"c":3,"d":null,"null":"e"} // 4 = { a: 2, b: null, c: 3, d: null, null: "e" }
{"fld":[null,null,[2],[3,4],"bb","cc"]} // 5
{"a":[[1,2],[3,4],{"aa":"one","bb":"two"},[5,6]]} // 6
{"a":["hi",2,null,[7,99],13]} // 7
{"a":{"0":2,"3":[7,99],"4":13,"x":"hi"}} // 8
Whereas Jacky Li's solution would produce the outer container for a as a plain object
{a:{"0":["1","2"],"1":["3","4"],"2":["5","6"]}} // 6: JackyLi's output
getargs() looks at the first given index for any level to determine whether this level will be an object (non-numeric index) or an array (numeric or empty), thus resulting in the output as shown in the listing bove (no. 6).
If the current object is an array then nulls get inserted wherever necessary to represent empty positions. Arrays are always consecutively numbered and 0-based).
Note, that in the example no. 8 the "autoincrement" for empty indices still works, even though we are dealing with an object now and not an array.
As far as I have tested it, my getargs() behaves pretty much identically to Chriss Roger's great jQuery $.deparam() plugin mentioned in the accepted answer. The main difference is that getargs runs without jQuery and that it does autoincrement in objects while $.deparam() will not do that:
JSON.stringify($.deparam('a[x]=hi&a[]=2&a[3][]=7&a[3][]=99&a[]=13').a);
results in
{"3":["7","99"],"x":"hi","undefined":"13"}
In $.deparam() the index [] is interpreted as an undefined instead of an autoincremented numerical index.
Here's how you could create a new jQuery function:
jQuery.unparam = function (value) {
var
// Object that holds names => values.
params = {},
// Get query string pieces (separated by &)
pieces = value.split('&'),
// Temporary variables used in loop.
pair, i, l;
// Loop through query string pieces and assign params.
for (i = 0, l = pieces.length; i < l; i++) {
pair = pieces[i].split('=', 2);
// Repeated parameters with the same name are overwritten. Parameters
// with no value get set to boolean true.
params[decodeURIComponent(pair[0])] = (pair.length == 2 ?
decodeURIComponent(pair[1].replace(/\+/g, ' ')) : true);
}
return params;
};
Thanks to him http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
Pretty easy :D
function params_unserialize(p){
var ret = {},
seg = p.replace(/^\?/,'').split('&'),
len = seg.length, i = 0, s;
for (;i<len;i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;}
This is really old question, but as i have coming - other people may coming to this post, and i want to a bit refresh this theme. Today no need to make custom solutions - there is URLSearchParams interface.
var paramsString = "q=URLUtils.searchParams&topic=api";
var searchParams = new URLSearchParams(paramsString);
//Iterate the search parameters.
for (let p of searchParams) {
console.log(p);
}
The only one limitation i know - this feature not supported in IE / Edge.
Here's my JavaScript implementation which I use in a server-side JScript ASP Classic page (demo):
// Transforms a query string in the form x[y][0][z][]=1 into {x:{y:[{z:[1]}]}}
function parseJQueryParams(p) {
var params = {};
var pairs = p.split('&');
for (var i=0; i<pairs.length; i++) {
var pair = pairs[i].split('=');
var indices = [];
var name = decodeURIComponent(pair[0]),
value = decodeURIComponent(pair[1]);
var name = name.replace(/\[([^\]]*)\]/g,
function(k, idx) { indices.push(idx); return ""; });
indices.unshift(name);
var o = params;
for (var j=0; j<indices.length-1; j++) {
var idx = indices[j];
var nextIdx = indices[j+1];
if (!o[idx]) {
if ((nextIdx == "") || (/^[0-9]+$/.test(nextIdx)))
o[idx] = [];
else
o[idx] = {};
}
o = o[idx];
}
idx = indices[indices.length-1];
if (idx == "") {
o.push(value);
}
else {
o[idx] = value;
}
}
return params;
}
I came up with this solution, which behaves like the .Net function HttpUtility.ParseQueryString.
In the result, the query string parameters are store in properties as lists of values, so that qsObj["param"] will be the same as calling GetValues("param") in .Net.
I hope you like it. JQuery not required.
var parseQueryString = function (querystring) {
var qsObj = new Object();
if (querystring) {
var parts = querystring.replace(/\?/, "").split("&");
var up = function (k, v) {
var a = qsObj[k];
if (typeof a == "undefined") {
qsObj[k] = [v];
}
else if (a instanceof Array) {
a.push(v);
}
};
for (var i in parts) {
var part = parts[i];
var kv = part.split('=');
if (kv.length == 1) {
var v = decodeURIComponent(kv[0] || "");
up(null, v);
}
else if (kv.length > 1) {
var k = decodeURIComponent(kv[0] || "");
var v = decodeURIComponent(kv[1] || "");
up(k, v);
}
}
}
return qsObj;
};
Here is how to use it:
var qsObj = parseQueryString("a=1&a=2&&b&c=3&d=&=e&");
To preview the result in the console juste type in:
JSON.stringify(qsObj)
Output:
"{"a":["1","2"],"null":["","b",""],"c":["3"],"d":[""],"":["e"]}"
There's a beautiful one-liner over at CSS-Tricks (original source from Nicholas Ortenzio):
function getQueryParameters(str) {
return (str || document.location.search).replace(/(^\?)/,'').split("&").map(function(n){return n = n.split("="),this[n[0]] = n[1],this}.bind({}))[0];
}
The really clever part is how it uses the anonymous function's this object, adding a key/value pair for each of the queries in the string. That said, there's some room for improvement. I've modified it a bit below, with the following changes:
Added handling of empty strings and non-string input.
Handled URI-encoded strings (%40->#, etc).
Removed the default use of document.location.search when the input was empty.
Changed the name, made it more readable, added comments.
function deparam(str) {
// Uses an empty 'this' to build up the results internally
function splitQuery(query) {
query = query.split('=').map(decodeURIComponent);
this[query[0]] = query[1];
return this;
}
// Catch bad input
if (!str || !(typeof str === 'string' || str instanceof String))
return {};
// Split the string, run splitQuery on each piece, and return 'this'
var queries = str.replace(/(^\?)/,'').split('&');
return queries.map(splitQuery.bind({}))[0];
}
use this :
// convert query string to json object
var queryString = "cat=3&sort=1&page=1";
queryString
.split("&")
.forEach((item) => {
const prop = item.split("=");
filter[prop[0]] = prop[1];
});
console.log(queryString);
This is my version in Coffeescript.
Also works for url like
http://localhost:4567/index.html?hello=[%22world%22]&world=hello#/home
getQueryString: (url)->
return null if typeof url isnt 'string' or url.indexOf("http") is -1
split = url.split "?"
return null if split.length < 2
path = split[1]
hash_pos = path.indexOf "#"
path = path[0...hash_pos] if hash_pos isnt -1
data = path.split "&"
ret = {}
for d in data
[name, val] = d.split "="
name = decodeURIComponent name
val = decodeURIComponent val
try
ret[name] = JSON.parse val
catch error
ret[name] = val
return ret
Here's a simple & compact one if you only want to quickly get the parameters from a GET request:
function httpGet() {
var a={},b,i,q=location.search.replace(/^\?/,"").split(/\&/);
for(i in q) if(q[i]) {b=q[i].split("=");if(b[0]) a[b[0]]=
decodeURIComponent(b[1]).replace(/\+/g," ");} return a;
}
It converts
something?aa=1&bb=2&cc=3
into an object like
{aa:1,bb:2,cc:3}
Creates a serialized representation of an array or object (can be used as URL query string for AJAX requests).
<button id='param'>GET</button>
<div id="show"></div>
<script>
$('#param').click(function () {
var personObj = new Object();
personObj.firstname = "vishal"
personObj.lastname = "pambhar";
document.getElementById('show').innerHTML=$.param(`personObj`));
});
</script>
output:firstname=vishal&lastname=pambhar
answers could use a bit of jQuery elegance:
(function($) {
var re = /([^&=]+)=?([^&]*)/g;
var decodeRE = /\+/g; // Regex for replacing addition symbol with a space
var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );};
$.parseParams = function(query) {
var params = {}, e;
while ( e = re.exec(query) ) {
var k = decode( e[1] ), v = decode( e[2] );
if (k.substring(k.length - 2) === '[]') {
k = k.substring(0, k.length - 2);
(params[k] || (params[k] = [])).push(v);
}
else params[k] = v;
}
return params;
};
})(jQuery);
fork at https://gist.github.com/956897
You can use the function .serializeArray() (Link) of jQuery itself. This function returns an array of key-value pair. Result example:
[
{ name: "id", value: "1" },
{ name: "version", value: "100" }
]

Categories