Related
I have a string similiar to document.cookie:
var str = 'foo=bar, baz=quux';
Converting it into an array is very easy:
str = str.split(', ');
for (var i = 0; i < str.length; i++) {
str[i].split('=');
}
It produces something like this:
[['foo', 'bar'], ['baz', 'quux']]
Converting to an object (which would be more appropriate in this case) is harder.
str = JSON.parse('{' + str.replace('=', ':') + '}');
This produces an object like this, which is invalid:
{foo: bar, baz: quux}
I want an object like this:
{'foo': 'bar', 'baz': 'quux'}
Note: I've used single quotes in my examples, but when posting your code, if you're using JSON.parse(), keep in your mind that it requires double quotes instead of single.
Update
Thanks for everybody. Here's the function I'll use (for future reference):
function str_obj(str) {
str = str.split(', ');
var result = {};
for (var i = 0; i < str.length; i++) {
var cur = str[i].split('=');
result[cur[0]] = cur[1];
}
return result;
}
The shortest way
document.cookie.split('; ').reduce((prev, current) => {
const [name, ...value] = current.split('=');
prev[name] = value.join('=');
return prev;
}, {});
Why exactly do you need JSON.parse in here? Modifying your arrays example
let str = "foo=bar; baz=quux";
str = str.split('; ');
const result = {};
for (let i in str) {
const cur = str[i].split('=');
result[cur[0]] = cur[1];
}
console.log(result);
note : The document.cookie (question headline) is semicolon separated and not comma separated (question) ...
An alternative using reduce :
var str = 'foo=bar; baz=quux';
var obj = str.split(/[;] */).reduce(function(result, pairStr) {
var arr = pairStr.split('=');
if (arr.length === 2) { result[arr[0]] = arr[1]; }
return result;
}, {});
A way to parse cookies using native methods like URLSearchParams and Object.fromEntries, avoiding loops and temporary variables.
Parsing document.cookie:
Object.fromEntries(new URLSearchParams(document.cookie.replace(/; /g, "&")))
For the scope of the question (cookies are separated by , and stored in variable str)
Object.fromEntries(new URLSearchParams(str.replace(/, /g, "&")))
Given an array a containing your intermediate form:
[['foo', 'bar'], ['baz', 'quux']]
then simply:
var obj = {};
for (var i = 0; i < a.length; ++i) {
var tmp = a[i];
obj[tmp[0]] = tmp[1];
}
To convert it to an object, just do that from the beginning:
var obj = {};
str = str.split(', ');
for (var i = 0; i < str.length; i++) {
var tmp = str[i].split('=');
obj[tmp[0]] = tmp[1];
}
Then, if you want JSON out of it:
var jsonString = JSON.stringify(obj);
parse cookies (IE9+):
document.cookie.split('; ').reduce((result, v) => {
const k = v.split('=');
result[k[0]] = k[1];
return result;
}, {})
I'm a fan of John Resig's "Search and don't replace" method for this sort of thing:
var str = 'foo=bar, baz=quux',
arr = [],
res = '{';
str.replace(/([^\s,=]+)=([^,]+)(?=,|$)/g, function ($0, key, value) {
arr.push('"' + key + '":"' + value + '"');
});
res += arr.join(",") + "}";
alert(res);
Working example: http://jsfiddle.net/cm6MT/.
Makes things a lot simpler without the need for JSON support. Of course, it's just as easy to use the same regular expression with exec() or match().
Whoops, I thought you wanted to convert to a JSON string, not an object. In that case, you only need to modify the code slightly:
var str = 'foo=bar, baz=quux',
res = {};
str.replace(/([^\s,=]+)=([^,]+)(?=,|$)/g, function ($0, key, value) {
res[key] = value;
});
console.log(res.foo);
//-> "bar"
Working example 2: http://jsfiddle.net/cm6MT/1/
Most of the above solutions fail with the __gads cookie that Google sets because it uses a '=' character in the cookie value.
The solution is to use a regular expression instead of calling split('='):
document.cookie.split(';').reduce((prev, current) => {
const [name, value] = current.split(/\s?(.*?)=(.*)/).splice(1, 2);
prev[name] = value;
return prev;
}, {});
That's pretty crappy data, as long as its not using ,= this would work on that data
var text = 'foo=bar, baz=quux',
pattern = new RegExp(/\b([^=,]+)=([^=,]+)\b/g),
obj = {};
while (match = pattern.exec(text)) obj[match[1]] = match[2];
console.dir(obj);
An alternate version of your updated solution that checks for the null/empty string and just returns an empty object and also allows for custom delimiters.
function stringToObject(str, delimiter) {
var result = {};
if (str && str.length > 0) {
str = str.split(delimiter || ',');
for (var i = 0; i < str.length; i++) {
var cur = str[i].split('=');
result[cur[0]] = cur[1];
}
}
return result;
}
first thing that occurred to me, I'll leave it as the original version, but cookies should not be empty otherwise there will be a json parse error
JSON.parse(`{"${document.cookie.replace(/=/g,'":"').replace(/; /g,'","')}"}`)
fast and reliable version - cookie to object
let c=document.cookie.split('; '),i=c.length,o={};
while(i--){let a=c[i].split('=');o[a[0]]=a[1]}
and short function for get single cookie
getCookie=e=>(e=document.cookie.match(e+'=([^;]+)'),e&&e[1])
function getCookie(){
var o=document.cookie.split("; ");
var r=[{}];
for(var i=0;i<o.length;i++){
r[o[i].split("=")[0]] = o[i].split("=")[1];
}
return r;
}
Just call getCookie() and it will return all cookies from the current website.
If you have a cookie called 'mycookie' you can run getCookie()['mycookie']; and it will return the value of the cookie 'mycookie'.
There is also a One-Line option:
function getCookie(){var o=document.cookie.split("; ");var r=[{}];for(var i=0;i<o.length;i++){r[o[i].split("=")[0]] = o[i].split("=")[1];}return r;}
This one can be used with the same methods as above.
I have a string of numbers like this:
var string= "1,2,3,4-8,15,17,18-21,22";
How can I split it into an array that forms: [1,2,3,4,5,6,7,8,15,17,18,19,20,21,22]
UPDATE:Okay, code coming up in just a bit... trying to get a jsfiddle up.
var mystring= "1,2,3,4-8,15,17,18-21,22";
var array1= mystring.split(",");
document.getElementById("output").innerHTML=array1;
var array2 = searchStringInArray ("-", array1);
document.getElementById("output2").innerHTML=array2;
function searchStringInArray (str, strArray) {
for (var j=0; j<strArray.length; j++) {
if (strArray[j].match(str)) return j;
}
return -1;
}
So around here I got stuck and was thinking there should be a better way. I know you have to search the array for hyphen split strings. But I failed to get them into another array that i could then insert into the first array.
https://jsfiddle.net/08au43ka/
var string= "1,2,3,4-8,15,17,18-21,22";
var arr=string.split(",");
var crr=[];
arr.forEach(function(a){
brr= a.split("-");
if(brr.length==2){
var o=parseInt(brr[0]);
var p=parseInt(brr[1]);
for(var i=o;i<=p;i++)
crr.push(i);
}
else
crr.push(parseInt(brr[0]));
})
console.log(crr);
You could split first by comma, then by minus and reduce the whole to a new array with an inner loop for missing values.
var string = "1,2,3,4-8,15,17,18-21,22",
result = string.split(',').reduce(function (r, a) {
var b = a.split('-').map(Number);
do {
r.push(b[0]);
b[0]++;
} while (b[0] <= b[1]);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can just replace the ranges:
var string = "1,2,3,4-8,15,17,18-21,22"
var regexRanges = /(\d+)-(\d+)/g;
var getRangeValues = function(range, start, end) {
return Array(end - start + 1).fill(+start).map((x, i)=> x + i);
};
var result = JSON.parse('[' + string.replace(regexRanges, getRangeValues) + ']');
console.log(result);
var string= "1,2,3,4-8,15,17,18-21,22";
var chunks = string.split(",");
var numbers = [];
for (var i = 0; i < chunks.length; i++) {
var chunk = chunks[i];
if (chunk.indexOf('-') < 0) {
numbers.push(parseInt(chunk));
}
else {
var pair = chunk.split('-');
for (var j = pair[0]; j <= pair[1]; j++) {
numbers.push(parseInt(j));
}
}
}
console.log(numbers);
Since there is no known method for me to achieve what you want most likely you will need to write your own.
I'd split that string by commas, then i'd iterate through array looking for anything containing dash in it, if it contains dash grab that array item, parse it
get left side, get right side, create loop from i = left to i<right, push items into original array.
Folks,
I have looked at underscore.string and string.js modules and still can't find a good way to do the following:
Suppose I have a query string string:
"!dogs,cats,horses!cows!fish"
I would like to pass it to a function that looks for all words that start with !, and get back an Array:
['dogs','cows','fish']
Similarly, the same function should return an array of words that start with ,:
['cats','horses]
Thanks!!!
You can use RegEx to easily match the split characters.
var string = "!dogs,cats,horses!cows!fish";
var splitString = string.split(/!|,/);
// ["dogs", "cats", "horses", "cows", "fish"]
The only issue with that is that it will possibly add an empty string at the beginning of the array if you start it with !. You could fix that with a function:
splitString.forEach(function(item){
if(item === ""){
splitString.splice(splitString.indexOf(item), 1)
}
});
EDIT:
In response to your clarificaiton, here is a function that does as you ask. It currently returns an object with the values commas and exclaim, each with an array of the corresponding elements.
JSBin showing it working.
function splitString(str){
var exclaimValues = [];
var expandedValues = [];
var commaValues = [];
var needsUnshift = false;
//First split the comma delimited values
var stringFragments = str.split(',');
//Iterate through them and see if they contain !
for(var i = 0; i < stringFragments.length; i++){
var stringValue = stringFragments[i];
// if the value contains an !, its an exclaimValue
if (stringValue.indexOf('!') !== -1){
exclaimValues.push(stringValue);
}
// otherwise, it's a comma value
else {
commaValues.push(stringValue);
}
}
// iterate through each exclaim value
for(var i = 0; i < exclaimValues.length; i++){
var exclaimValue = exclaimValues[i];
var expandedExclaimValues = exclaimValue.split('!');
//we know that if it doesn't start with !, the
// the first value is actually a comma value. So move it
if(exclaimValue.indexOf('!') !== 0) commaValues.unshift(expandedExclaimValues.shift());
for(var j = 0; j < expandedExclaimValues.length; j++){
var expandedExclaimValue = expandedExclaimValues[j];
//If it's not a blank entry, push it to our results list.
if(expandedExclaimValue !== "") expandedValues.push(expandedExclaimValue);
}
}
return {comma: commaValues, exclaim: expandedValues};
}
So if we do:
var str = "!dogs,cats,horses!cows!fish,comma!exclaim,comma2,comma3!exclaim2";
var results = splitString(str)
results would be:
{
comma: ["comma3", "comma", "horses", "cats", "comma2"],
exclaim: ["dogs", "cows", "fish", "exclaim", "exclaim2"]
}
I have the following array:
var mystr = "Name[Daniel],Name2[Alguien],Date[2009],Date[2014]";
How can I convert it to an array like this:
var array = ['Daniel','Alguien','2009',2014];
You can do it this way:
var mystr = "Name[Daniel],Name2[Alguien],Date[2009],Date[2014]";
var array = mystr.match(/\[.+?\]/g).map(function(value){ // searches for values in []
return value.replace(/[\[\]]/g,""); // removes []
});
Try to use following code , as you can see the string is split by comma and then using regular expressions the necessary part has been pushed to new array
var mystr = "Name[Daniel],Name2[Alguien],Date[2009],Date[2014]";
var array = mystr.split(",");
re = /\[(.*)\]/;
var newArray = [];
for (var i = 0; i < array.length; i++) {
newArray.push(array[i].match(re)[1]);
}
newArray = ['Daniel', 'Alguien', '2009', 2014];
I have the following array
var arr=[[10,20,30],[12,21,33],[13,23,35]];
How can I convert that array to JSON.
Desired result
myJSONarr=[
{"x":10 ,"y":20,"z":30},
{"x":12 ,"y":21,"z":33},
{"x":13, "y":23,"z":35}
];
I'm guessing I will have to define sting array
var objArray=["x","y","z"];
and do loop over these two values with the eval() function.
Any help is greatly appreciated.
if you use jquery:
var arr=[[10,20,30],[12,21,33],[13,23,35]],
myjson = JSON.stringify($.map(arr,function(a){return {x:a[0],y:a[1],z:a[2]}}));
http://jsfiddle.net/herostwist/yDRwh/
if you use prototype:
var myjson = JSON.stringify([[10,20,30],[12,21,33],[13,23,35]].map(function(a){
return {x:a[0],y:a[1],z:a[2]}}));
http://jsfiddle.net/herostwist/yDRwh/1/
My version. Edit: I didn't twig objArray wasn't part of the problem, but the OP's suggestion as part of the solution. Oh well, I like it anyway.
var arr=[[10,20,30],[12,21,33],[13,23,35]];
var objArray=["x","y","z"];
var myJSONarr = [];
for (var idx = 0; idx != arr.length; idx++) {
var row = {};
for (var idx2 = 0; idx2 != objArray.length; idx2++) {
row[objArray[idx2]] = arr[idx][idx2];
}
myJSONarr.push(row);
}
alert(JSON.stringify(myJSONarr));
Many different answers, here's another:
http://jsfiddle.net/Vecqc/
<textarea id="text" style="width: 100%;"></textarea>
var arr = [[10,20,30],[12,21,33],[13,23,35]];
var stringify = [];
for (var i = 0; i < arr.length; i++) {
stringify[i] = {'x':arr[i][0],'y':arr[i][0],'z':arr[i][0]};
}
document.getElementById('text').value = JSON.stringify(stringify);
Assuming you just want to map the values to JavaScript objects†:
var objs = [];
for(var i = 0, l = arr.length; i < l; i++) {
var p = arr[i];
objs.push({x: p[0], y: p[1], z: p[2]});
}
If you really want to create a JSON string, then you can pass this array to JSON.stringify. JSON is available in all modern browser and can be loaded for older ones.
†: Why am I assuming here? Because people confuse JSON with JavaScript object literals. In your code, myJSONarr is not JSON. It is an array of JS objects. It would be JSON if the data would be contained in a string:
var myJSONarr = '[{"x":10, "y":20, "z":30}, ...]';
JSON != JavaScript object
What you are describing is not merely a JSON conversion. You actually have an array full of three element arrays of numbers, and what you are wanting is JSON for an array of hashes where each triplet becomes a hash over "x","y","z".
Anyway, if you want a simple .toJSON() function, Prototype.js includes a .toJSON() function onto most objects that makes it really easy.
http://www.prototypejs.org/learn/json
Untested...
var arr=[[10,20,30],[12,21,33],[13,23,35]];
var myarrOfXYZ = arr.collect(function(T){ return $H({ x: T[0], y: T[1], z: T[2] }) });
var myJSON = myarrOfXYZ.toJSON();
Note that prototype also provides a function "zip" that can be used on line 2 instead of $H
Just loop through the array and create a string from each array inside it, then join the strings to form the JSON string:
var items = [];
for (var i = 0; i < arr.length; i++) {
items.push('{"x":'+arr[i][0]+',"y":'+arr[i][1]+',"z":'+arr[i][2]+'}');
}
var myJSONarr = '[' + items.join(',') + ']';
First:
var arr = [[10,20,30], [12,21,33], [13,23,35]];
var arr2 = [];
for (var i in arr) {
var a = arr[i];
arr2.push({
x: a[0],
y: a[1],
z: a[2]
});
}
Or, using higher-order functions:
var labels = ["x", "y", "z"];
var arr = [[10,20,30], [12,21,33], [13,23,35]];
var arr2 = arr.map(function(a) {
return a.reduce(function(prev, curr, i) {
prev[labels[i]] = curr;
return prev;
}, {});
});
Then directly convert the new array to JSON.