Parse values out of paramaterized strings in javascript - javascript

Say I have a string, such as:
var map = "/directory/:id/thumbnails/:size";
And I want to use that to map against another string (essentially, the same thing that Rails uses to define Routes), such as:
var str = "/directory/10/thumbnails/large";
I would like to "compare" the two strings, and return a Key-Value Pair or JSON Object that represents the parts of str that map to map, which in my example above, would look like:
obj = {
'id' : '10',
'size' : 'large'
}
Would this be a good fit for JavaScript Regex? Can anyone help me?

I found it easier to just write the code for this than to explain :)
var map = "/directory/:id/thumbnails/:size";
var str = "/directory/10/thumbnails/large";
var obj = {};
var mapArr = map.split('/');
var strArr = str.split('/');
if (mapArr.length != strArr.length) return false;
for (var i = 0; i < mapArr.length; i++)
{
var m = mapArr[i];
var s = strArr[i];
if (m.indexOf(":") != 0) continue;
m = m.substring(1);
obj[m] = s;
document.write(m + " = ");
document.write(obj[m]);
document.write("<br/>");
}
You can also see it in action here => http://jsfiddle.net/5qFkb/
Do ask if you have any questions, but the code should be self-explanatory. Also be aware that there is no usual null checking and stuff I'd usually put in - this is just meant as a quick and dirty proof of concept.
Oh and in case it wasn't clear from my answer; no, I wouldn't use regex, because then I'd have two problems instead of one.

Related

JS: Check Query String for GET variables that are not in an array?

Let's say I have an address of:
www.example.com/index.php?a=1&b=2&c=3
I want to enter that into an input field like this (value would obviously initially be blank):
<input id="my-input-field" value="www.example.com/index.php?a=1&b=2&c=3">
Then I want JS to parse everything after the ?, take all of the queries ("a", "b", "c") and see if they exist in an array().
Then I want to display a message stating that some of the items in the given URL were missing - but that's the easy part.
The part that I'm having trouble figuring out is: how to break down the URL and only find the first part of each query?
I understand how to strip everything before the question mark (including the question mark):
var str = "www.example.com/index.php?a=1&b=2&c=3";
str = str.substring(str.indexOf("?") + 1);
alert(str);
Fiddle: http://jsfiddle.net/xx3fwhvv/
This returns: a=1&b=2&c=3
The next step could be to split the string up per each &?
var str = "a=1&b=2&c=3";
str = str.split("&");
alert(str);
Fiddle: http://jsfiddle.net/3Lo24byo/
This returns: a=1,b=2,c=3
We can then remove everything after the ='s sign like this:
var str = 'a=1';
str = str.substring(0, str.indexOf('='));
alert(str);
Fiddle: http://jsfiddle.net/vfzvu5mh/
This results in: a
The thing now is how do I loop through the array and do this for each item? That would be the step I need to take.
Then I need to have an array like:
var myArray = array('a','c','d');
In the above array, cross checking the array that we created above to see if any of the values match up should return b as not matching up, as it's not in myArray.
This is where I'm stuck. Any help is appreciated. I'm not very good with JS but I've been working at this trying to figure it out.
All together so far, the code would look something like this:
var str = "www.example.com/index.php?a=1&b=2&c=3";
newStr = str.substring(str.indexOf("?") + 1);
strArray = newStr.split("&");
i = 1;
for {
newStrArray = strArray[i].substring(0, strArray[i].indexOf('='));
i++;
}
The above doesn't work for me, but something like that any way.
EDIT (I'll be actively editing this part until the question is answered):
var str = "www.example.com/index.php?a=1&b=2&c=3";
var newStr = str.substring(str.indexOf("?") + 1);
var myStringArray = newStr.split("&");
var arrayLength = myStringArray.length;
for (var i = 0; i < arrayLength; i++) {
myStringArray = myStringArray[i].substring(0, myStringArray[i].indexOf('='));
alert(myStringArray[i]);
}
Current Fiddle: https://jsfiddle.net/03ho0nbz/
First off, you're overwriting your array with the result of a substring:
myStringArray = myStringArray[i].substring(0, myStringArray[i].indexOf('='));
myStringArray receives the results of the substring, turning it into a string.
To compare myArray with otherArray and see if an element not exists in myArray you can use the indexOf() function:
var myArray = ['a', 'c', 'd'];
var otherArray = ['a', 'b', 'c'];
for(var i=0;i<otherArray.length;i++) {
if(myArray.indexOf(otherArray[i]) === -1) {
console.log('myArray does not have', otherArray[i]); // myArray does not have b
}
}
Going by your example this would create a loop looking something like:
var str = "www.example.com/index.php?a=1&b=2&c=3";
var newStr = str.substring(str.indexOf("?") + 1);
var myStringArray = newStr.split("&");
var myArray = ['a', 'c', 'd'];
for (var i = 0; i < myStringArray.length; i++) {
var eqIndex = myStringArray[i].indexOf('=');
if(eqIndex !== -1) {
var key = myStringArray[i].substring(0, eqIndex);
if(myArray.indexOf(key) === -1) {
alert(key, "not in myArray!");
}
}
}
Note that this way of writing JS is fine for learning practices, but if you intend to use JS in a professional setting, please read up on some JS good practices.
What i would do is to fiddle around with JS like you're doing, try and see if you can buy some JS good practices books and also look at how popular frameworks solve things. For professional purpose it's almost always a good idea to use a framework that's well maintained and supported. For example if you would use underscore in this case you could do something like:
var paramKeys = _.chain("a=1&b=2&c=3".split('&')).map(function(params) {
var p = params.split('=');
return p[0];
}).value();
_.difference(paramKeys, ['a', 'c', 'd']) // "b"
#mattroberts33 I am unable to understand why you are checking first parameter in the url, is there anything deference from www.example.com/index.php?a=1&b=2&c=3 to www.example.com/index.php?b=2&a=1&c=3. I would encourage read parameters based on the keys instead of index. In any url query parameters might jumbled.
Below method will return parameter by passing key and url to the method:
var getParameterByName = function (name, url) {
name = name.replace(/[\[]/, '\\\[').replace(/[\]]/, '\\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
if (url) {
var results = regex.exec(url);
} else {
var results = regex.exec(location.search);
}
return results == null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));};
If you still wants to get based on index we can modify above method, But that is not encouraging.

Create variables based on array

I have the following array and a loop fetching the keys (https://jsfiddle.net/ytm04L53/)
var i;
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
for (i = 0; i < feeds.length; i++) {
var feed = feeds[i];
alert(feed.match(/\d+$/));
}
The array will always contain different number of keys, What I would like to do is either use these keys as variables and assign the value after the : semicolon as its value or just create a new set of variables and assign the values found on these keys to them.
How can I achieve this? so that I can then perform some sort of comparison
if (test_user > 5000) {dosomething}
update
Thanks for the answers, how can I also create a set of variables and assign the array values to them? For instance something like the following.
valCount(feeds.split(","));
function valCount(t) {
if(t[0].match(/test_user_.*/))
var testUser = t[0].match(/\d+$/);
}
Obviously there is the possibility that sometimes there will only be 1 key in the array and some times 2 or 3, so t[0] won't always be test_user_
I need to somehow pass the array to a function and perform some sort of matching, if array key starts with test_user_ then grab the value and assign it to a define variable.
Thanks guys for all your help!
You can't (reasonably) create variables with dynamic names at runtime. (It is technically possible.)
Instead, you can create object properties:
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
var obj = {};
feeds.forEach(function(entry) {
var parts = entry.split(":"); // Splits the string on the :
obj[parts[0]] = parts[1]; // Creates the property
});
Now, obj["test_user_201508_20150826080829.txt"] has the value "12345".
Live Example:
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
var obj = {};
feeds.forEach(function(entry) {
var parts = entry.split(":");
obj[parts[0]] = parts[1];
});
snippet.log(obj["test_user_201508_20150826080829.txt"]);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
You can do it like this, using the split function:
var i;
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
for (i = 0; i < feeds.length; i++) {
var feed = feeds[i];
console.log(feed.split(/[:]/));
}
This outputs:
["test_user_201508_20150826080829.txt", "12345"]
["test_user_list20150826", "666"]
["test_list_Summary20150826.txt", "321"]
Use the split method
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
feedMap = {}
for (i = 0; i < feeds.length; i++) {
var temp = feeds[i].split(':');
feedMap[temp[0]] = temp[1];
}
Yields:
{
"test_user_201508_20150826080829.txt":"12345",
"test_user_list20150826":"666",
"test_list_Summary20150826.txt":"321"
}
And can be accessed like:
feedMap["test_user_201508_20150826080829.txt"]
Here is a codepen
it is not very good idea but if you really need to create variables on-the-run here's the code:
for (i = 0; i < feeds.length; i++)
{
var feed = feeds[i];
window[feed.substring(0, feed.indexOf(":"))] = feed.match(/\d+$/);
}
alert(test_user_201508_20150826080829)
Of course you cannot have any variable-name-string containing banned signs (like '.')
Regards,
Michał

How Do I Parse a Pipe-Delimited String into Key-Value Pairs in Javascript

I want to parse the following sort of string into key-value pairs in a Javascript object:
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
Each word of 4 capital letters (PLNC, SUBD, and CITY) is to be a key, while the word(s) in the immediately following pipe are to be the value (the first one, for PLNC, would be undefined, the one for SUBD would be 'Pines', the one for CITY would be 'Fort Myers').
Note that '|EOR|' immediately precedes every key-value pair.
What is the best way of doing this?
I just realised it's technically a csv format with interesting line endings. There are limitations to this in that your variable values cannot contain any | or < br> since they are the tokens which define the structure of the string. You could of course escape them.
var stringVar = 'PLNC||0|EOR|<br>SUBD|Pines|1|EOR|<br>CITY|Fort Myers|1|EOR|<br>';
function decodeString(str, variable_sep, line_endings)
{
var result = [];
var lines = str.split(line_endings);
for (var i=0; i<lines.length; i++) {
var line = lines[i];
var variables = line.split(variable_sep);
if (variables.length > 1) {
result[variables[0]] = variables[1];
}
}
return result;
}
var result = decodeString(stringVar, "|", "<br>");
console.log(result);
If you have underscore (and if you don't, then just try this out by opening up your console on their webpage, because they've got underscore included :)
then play around with it a bit. Here's a start for your journey:
_.compact(stringVar.split(/<br>|EOR|\|/))
Try
function parse(str) {
var str = str.replace(/<br>/gi);
console.log(str);
var arr = str.split('|');
var obj = {};
for (var i=0; i<arr.length; i=i+4) {
var key = arr[i] || '';
var val_1 = arr[i+1] || '';
var val_2 = arr[i+2] || '';
if(key) {
obj[key] = val_1 + ':' + val_2; //or similar
}
}
return obj;
}
DEMO
This will work on the particular data string in the question.
It will also work on other data string of the same general format, but relies on :
<br> being discardable before parsing
every record being a group of 4 string elements delineated by | (pipe)
first element of each record is the key
second and third elements combine to form the value
fourth element is discardable.

Javascript regular expressions for Query Builder

This may have been asked in the past but I couldnt find a suitable answer. What I am looking for is a method to extract parameters from an sql query such as below. The queries will always be an EXEC statement followed by the query name, and possible parameters.
Here is an example of what I may recieve
EXEC [dbo].[myProcedure] #Param1
This could also be as follows
EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3
Those are the only types of queries that the input will take. As for why I am doing this, well thats another question all together, and I am pretty set on going down this route.
What I am looking for is to be able to take the above strings and produce an array of values such as
['#Param1','#Param2','#Param3',....]
I originally tried to just parese using a simple while statement but I seem to have huge issues there.
I hope this question makes sense,
Cheers,
Nico
[Edit]
Sorted this by using the following statement
function eParams(e) {
var i = e.indexOf('#');
if (i <= 0)
return;
e = e.substring(i);
var p = e.split(',');
var eList = [];
var s = '';
for (var i = 0, j = p.length - 1; i <= j; i++) {
var sP = p[i].trim();
if (sP.indexOf('#') < 0)
continue;
eList.push(sP);
}
}
var str = 'EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3';
(str).match(/(#[^\s,]+)/g);
will return an array.
var s = "EXEC [dbo].[myProcedure] #Param1, #Param2, #Param3";
var i = s.indexOf('#');
var a = s.substr(i).split(/\s*,\s*/);
(error checking omitted)

Javascript / DOM, parsing Key/Value string

I send a string from a server to the Firefox Browser in the format below:
"KEY:a1 VAL:123.45"
And this string can contain many such records.
Here is the code I have written:
var e;
var reply = request.responseText;
var txt = "", tab, key = "", val = "";
var x = reply.getElementsByTagName("KEY:");
for(i = 0; i < x.length; i++)
{
txt = x[i].childNodes[0].nodeValue; // "KEY:%c%c VAL:%.2F"
tab = txt.split(":");
key = "table_" + tab[1].substring(0,1);
val = tab[2];
e = document.getElementById(key);
e.innerHTML = val;
e.style.display = "block";
}
val displays "KEY:a1 VAL:123.45" instead of the expected "123.45" (and of course the key variable is also wrong, not matching a table cell, just picking the first one in the table).
I don't even know how to display the key and val values (document.write() and alert() do nothing and I don't see how to trace this code in Firefox).
Any idea, tip, correction, or code example is welcome but please don't recommend using any library, I want to do it with little code.
EDIT: from the two comments, I understand that there are two distinct ways to proceed: either using DOM objects and HTML tags, or using 'strings'. I would prefer to keep using the format above, so please guide me to a 'string' solution. Thanks!
You can use a simple regular expression to extract the information from the string:
var value = "KEY:a1 VAL:123.45"​,
pattern = /KEY:(\S+) VAL:(.+)$/g;
var result = pattern.exec(value);
// result[1] == 'a1'
// result[2] == '123.45'
In your case, you'd use request.responseText instead of value.

Categories

Resources