Convert a multidimensional javascript array to JSON? - javascript

What is the best way of converting a multi-dimensional javascript array to JSON?

Most of the popular JavaScript frameworks have JSON utility functions included. For instance, jQuery has a function that directly calls a url and loads the JSON result as an object : http://docs.jquery.com/Getjson
However, you can get an open-source JSON parser and stringifier from the json website :
https://github.com/douglascrockford/JSON-js
Then, simply include the code and use the JSON.stringify() method on your array.

The "best" way has been provided by the other posters. If you don't need the full encoding features of the referenced libraries, and only need to encode simple arrays, then try this:
<!DOCTYPE html>
<html>
<head>
<title>Simple functions for encoding Javascript arrays into JSON</title>
<script type="text/javascript">
window.onload = function() {
var a = [
[0, 1, '2', 3],
['0', '1', 2],
[],
['mf', 'cb']
],
b = [
0, '1', '2', 3, 'woohoo!'
];
alert(array2dToJson(a, 'a', '\n'));
alert(array1dToJson(b, 'b'));
};
function array2dToJson(a, p, nl) {
var i, j, s = '{"' + p + '":[';
nl = nl || '';
for (i = 0; i < a.length; ++i) {
s += nl + array1dToJson(a[i]);
if (i < a.length - 1) {
s += ',';
}
}
s += nl + ']}';
return s;
}
function array1dToJson(a, p) {
var i, s = '[';
for (i = 0; i < a.length; ++i) {
if (typeof a[i] == 'string') {
s += '"' + a[i] + '"';
}
else { // assume number type
s += a[i];
}
if (i < a.length - 1) {
s += ',';
}
}
s += ']';
if (p) {
return '{"' + p + '":' + s + '}';
}
return s;
}
</script>
</head>
<body>
</body>
</html>

Not sure I fully understand your question, but if you are trying to convert the object into a string of JSON then you probably want to look at the native JSON support in all the new browsers. Here's Resig's post on it. For browsers that don't yet support it try the json2.js library. JSON.stringify(obj) will convert your object to a string of JSON.

This will convert all combinations of arrays within objects and vice versa including function names:
function isArray(a){var g=a.constructor.toString();
if(g.match(/function Array()/)){return true;}else{return false;}
}
function objtostring(o){var a,k,f,freg=[],txt; if(typeof o!='object'){return false;}
if(isArray(o)){a={'t1':'[','t2':']','isarray':true}
}else {a={'t1':'{','t2':'}','isarray':false}}; txt=a.t1;
for(k in o){
if(!a.isarray)txt+="'"+k+"':";
if(typeof o[k]=='string'){txt+="'"+o[k]+"',";
}else if(typeof o[k]=='number'||typeof o[k]=='boolean'){txt+=o[k]+",";
}else if(typeof o[k]=='function'){f=o[k].toString();freg=f.match(/^function\s+(\w+)\s*\(/);
if(freg){txt+=freg[1]+",";}else{txt+=f+",";};
}else if(typeof o[k]=='object'){txt+=objtostring(o[k])+",";
}
}return txt.substr(0,txt.length-1)+a.t2;
}

You could use the encode function of this library.

I've modified a bit the code previously provided... because a JSON has this format: [{"object":{"property_1":"value_1","property_2":"value_2"}}]
So, the code would be...
<!DOCTYPE html>
<html>
<head>
<title>Simple functions for encoding Javascript arrays into JSON</title>
<script type="text/javascript">
window.onload = function(){
var a = [['property_1','value_1'],['property_2', 'value_2']];
alert("Comienzo..., paso ////"+a+"\\\\\\ a formato JSON");
var jsonSerialized = array2dToJson(a, 'object');
alert(jsonSerialized);
};
// Estructura de JSON [{"object":{"property_1":"value_1","property_2":"value_2"}}]
function array2dToJson(a, p, nl) {
var i, j, s = '[{"' + p + '":{';
nl = nl || '';
for (i = 0; i < a.length; ++i) {
s += nl + array1dToJson(a[i]);
if (i < a.length - 1) {
s += ',';
}
}
s += nl + '}}]';
return s;
}
function array1dToJson(a, p) {
var i, s = '';
for (i = 0; i < a.length; ++i) {
if (typeof a[i] == 'string') {
s += '"' + a[i] + '"';
}
else { // assume number type
s += a[i];
}
if (i < a.length - 1) {
s += ':';
}
}
s += '';
if (p) {
return '{"' + p + '":' + s + '}';
}
return s;
}
</script>
</head>
<body>
<h1>Convertir un Array a JSON...</h1>
</body>
</html>

var t = {}
for(var i=0;i<3;i++) {
var _main = {};
var _dis = {}
var _check = {};
_main["title"] = 'test';
_main["category"] = 'testing';
_dis[0] = '';
_dis[1] = '';
_dis[2] = '';
_dis[3] = '';
_check[0] = 'checked';
_check[1] = 'checked';
_check[2] = 'checked';
_check[3] = 'checked';
_main['values'] = _check;
_main['disabled'] = _dis;
t[i] = _main;
}
alert(JSON.stringify(t));
Try this

use this code and very simple develop for more two array
function getJSON(arrayID,arrayText) {
var JSON = "[";
//should arrayID length equal arrayText lenght and both against null
if (arrayID != null && arrayText != null && arrayID.length == arrayText.length) {
for (var i = 0; i < arrayID.length; i++) {
JSON += "{";
JSON += "text:'" + arrayText[i] + "',";
JSON += "id:'" + arrayID[i] + "'";
JSON += "},";
}
}
JSON += "]"
JSON = Function("return " + JSON + " ;");
return JSON();
}
and 3 array
function getJSON(arrayID, arrayText, arrayNumber) {
var JSON = "[";
if (arrayID != null && arrayText != null && arrayNumber!=null && Math.min(arrayNumber.length,arrayID.length)==arrayText.length) {
for (var i = 0; i < arrayID.length; i++) {
JSON += "{";
JSON += "text:'" + arrayText[i] + "',";
JSON += "id:'" + arrayID[i] + "',";
JSON += "number:'" + arrayNumber[i] + "'";
JSON += "},";
}
}
JSON += "]"
JSON = Function("return " + JSON + " ;");
return JSON();
}

JavaScript will correctly encode an object:
var a = new Object;
var a = {};
JavaScript will not encode an array:
var a = new Array();
var a = [];

Related

Only show objects in array that contain a specific string

I was trying to make something where you can type a string, and the js only shows the objects containing this string. For example, I type Address1 and it searches the address value of each one then shows it (here: it would be Name1). Here is my code https://jsfiddle.net/76e40vqg/11/
HTML
<input>
<div id="output"></div>
JS
var data = [{"image":"http://www.w3schools.com/css/img_fjords.jpg","name":"Name1","address":"Address1","rate":"4.4"},
{"image":"http://shushi168.com/data/out/114/38247214-image.png","name":"Name2","address":"Address2","rate":"3.3"},
{"image":"http://www.menucool.com/slider/jsImgSlider/images/image-slider-2.jpg","name":"Name3","address":"Address3","rate":"3.3"}
];
var restoName = [], restoAddress = [], restoRate = [], restoImage= [];
for(i = 0; i < data.length; i++){
restoName.push(data[i].name);
restoAddress.push(data[i].address);
restoRate.push(data[i].rate);
restoImage.push(data[i].image);
}
for(i = 0; i < restoName.length; i++){
document.getElementById('output').innerHTML += "Image : <a href='" + restoImage[i] + "'><div class='thumb' style='background-image:" + 'url("' + restoImage[i] + '");' + "'></div></a><br>" + "Name : " + restoName[i] + "<br>" + "Address : " + restoAddress[i] + "<br>" + "Rate : " + restoRate[i] + "<br>" + i + "<br><hr>";
}
I really tried many things but nothing is working, this is why I am asking here...
Don't store the details as separate arrays. Instead, use a structure similar to the data object returned.
for(i = 0; i < data.length; i++){
if (data[i].address.indexOf(searchedAddress) !== -1) { // Get searchedAddress from user
document.getElementById("output").innerHTML += data[i].name;
}
}
Edits on your JSFiddle: https://jsfiddle.net/76e40vqg/17/
Cheers!
Here is a working solution :
var data = [{"image":"http://www.w3schools.com/css/img_fjords.jpg","name":"Name1","address":"Address1","rate":"4.4"},
{"image":"http://shushi168.com/data/out/114/38247214-image.png","name":"Name2","address":"Address2","rate":"3.3"},
{"image":"http://www.menucool.com/slider/jsImgSlider/images/image-slider-2.jpg","name":"Name3","address":"Address3","rate":"3.3"}
];
document.getElementById('search').onkeyup = search;
var output = document.getElementById('output');
function search(event) {
var value = event.target.value;
output.innerHTML = '';
data.forEach(function(item) {
var found = false;
Object.keys(item).forEach(function(val) {
if(item[val].indexOf(value) > -1) found = true;
});
if(found) {
// ouput your data
var div = document.createElement('div');
div.innerHTML = item.name
output.appendChild(div);
}
});
return true;
}
<input type="search" id="search" />
<div id="output"></div>

generate varname in jquery

In PHP it's easy to create variables.
for($i=1; $i<=$ges; $i++) {
${"q" . $i} = $_POST["q".i];
${"a" . $i} = $_POST["a".i];
}
The result is $a1 = $_POST["q1];
How is the right way for that in jQuery?
I need to create it dynamicly for an ajax dataset.
for (var i = 1; i < ges; ++i) {
var finalVar = "input[name='a" + i + "']:checked";
var qtext = $("#q"+ i).text();
if ($(finalVar).val() == null) {
qvar = 0
} else {
qvar = $(finalVar).val();
}
//write question text and value in q1, a1, q2, a2,...
//generate ajax data
params = params + "q" + i + ":" + "q" + i + ", " + "a" + i + ":" + "a" + i + ","
}
I want to set the question text in q1 and the answer in a1.
Well if am not wrong you want to accumulate answers related to questions from the HTML and want to send the data through ajax..
So u can do something like this:
var QnA = {};
$('.eventTrigger').click(function(e) {
e.preventDefault();
$('#parent').find('.QnA').each(function() {
QnA[$(this).find('.Que').text()] = $(this).find('.Ans').val();
})
console.log(QnA);
})
https://jsfiddle.net/jt4ow335/1/
The only thing you can do about it, is:
var obj = {}
for(var i = 0; i < 10; i++)
obj['cell'+i] = i
console.log(obj)
and pass obj as data

Javascript object serialization function

I need a function that can serialize object of type {"a":"val", "b":{}, "c":[{}]} without JSON.stringify (cause the environment simply does not has JSON object) or using jquery and any other library. The code bellow is what I have at this moment:
function objToString(obj) {
if (obj == null) return null;
var index = 0;
var str = '{';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += index != 0 ? "," : "";
str += '"' + p + '":' + (typeof (obj[p]) == 'object' ? objToString(obj[p]) : itemToJsonItem(obj[p]));
index++;
}
}
str += "}";
return str;
}
function itemToJsonItem(item) {
return isNaN(item) ? '"' + item + '"' : item;
}
This function can deal with objects, nested objects but not with arrays. Node "c" from mentioned object will looks like "c":{"0":{...}} and not like array. Unsurprising "c".constructor === Array is false cause it interpreted as function and not as array. This is complete code where you can see what happens.
<div id="div_result"></div>
<script>
var test = { "a": "val", "b": [{"c":"val c"}]};
function objToString(obj) {
if (obj == null) return null;
var index = 0;
var str = '{';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += index != 0 ? "," : "";
str += '"' + p + '":' + (typeof (obj[p]) == 'object' ? objToString(obj[p]) : itemToJsonItem(obj[p]));
index++;
}
}
str += "}";
return str;
}
function itemToJsonItem(item) {
return isNaN(item) ? '"' + item + '"' : item;
}
document.getElementById("div_result").innerHTML = objToString(test);
</script>
I will really appreciate help, at this moment serialized object created by toSerialize function inside of each object but we want to make it with outside standard function.
Try to use JSON 3. It is polyfill library for window.JSON. It exposes JSON.stringify and JSON.parse methods.

Loop thru object to output icons javascript

Sorry for the poor title–I didn't know what to put.
Anyways, I have this object I want to loop thru in order to dynamically output some icons onclick:
<button id="btn">hit me</button>
var socialMedia = {
facebook: "http://facebook.com",
twitter: "http://twitter.com",
instagram: "http://instagram.com",
dribbble: "http://dribbble.com",
social: function() {
var output = "<ul>";
var myList = document.querySelectorAll('.socialSpot');
for (var key in arguments[0]) {
output += '<li><a href="' + this[key] + '"><img src="_assets/'
+ key + '.png" alt="' + key + 'icon"></a></li>';
}
output += '</ul>';
for (var i = myList.length - 1; i >= 0; i--) {
myList[i].innerHTML = output;
};
}
};
var theBtn = document.getElementById('btn');
theBtn.addEventListener('click', function() {
socialMedia.social(socialMedia);
}, false);
I know I could remove the method and instantiate it while passing the object, but I was wondering how I could go about it this way. In other words, I want to leave the function as a method of the socialMedia {}. Any pointers?
Just add a if (typeof obj[key] != "string") continue; test to your loop:
…
social: function(obj) {
var output = "<ul>";
var myList = document.querySelectorAll('.socialSpot');
for (var key in obj) {
if (typeof this[key] != "string") continue;
output += '<li><a href="' + this[key] + '"><img src="_assets/'
+ key + '.png" alt="' + key + 'icon"></a></li>';
}
output += '</ul>';
for (var i = myList.length - 1; i >= 0; i--) {
myList[i].innerHTML = output;
};
}
Of course, simply using another object would be so much cleaner:
var socialMedia = {
data: {
facebook: "http://facebook.com",
twitter: "http://twitter.com",
instagram: "http://instagram.com",
dribbble: "http://dribbble.com"
},
social: function(obj) {
var data = obj || this.data;
var output = "<ul>";
for (var key in data) {
output += '<li><a href="' + data[key] + '"><img src="_assets/'
+ key + '.png" alt="' + key + 'icon"></a></li>';
}
output += '</ul>';
var myList = document.querySelectorAll('.socialSpot');
for (var i = myList.length - 1; i >= 0; i--) {
myList[i].innerHTML = output;
};
}
};
var theBtn = document.getElementById('btn');
theBtn.addEventListener('click', function() {
socialMedia.social();
}, false);
You don't need to pass in socialMedia to have access to the socialMedia object inside of the social function. As the social function's execution context is socialMedia's execution context, this will be bound to socialMedia inside of social. In other words
var socialMedia = {
...
social: function(){
var socialMedia = this;
//socialMedia.facebook == this.facebook
//socialMedia.twitter == this.twitter
//you can loop through this inside of for in to get these properties
//(although you may want to make sure to avoid the function again)
}
};
this will be available no matter what, so you can call socialMedia.social() without any arguments.
You could do it with an easier API and still keep both together (without having them both together)
var socialMedias = (function() {
var medias = {
facebook: "http://facebook.com",
twitter: "http://twitter.com",
instagram: "http://instagram.com",
dribbble: "http://dribbble.com",
};
return function(socials) {
if (!socials) {
return medias;
}
var output = "<ul>";
var myList = document.querySelectorAll('.socialSpot');
for (var key in socials) {
output += '<li><a href="' + this[key] + '"><img src="_assets/'
+ key + '.png" alt="' + key + 'icon"></a></li>';
}
output += '</ul>';
for (var i = myList.length - 1; i >= 0; i--) {
myList[i].innerHTML = output;
};
};
})();
So socialMedias() return the map, individual entry can be fetched like socialMedias().facebook and socialMedias(myArgument) would run the method

mustache - render entire data structure

Is there some way to render all the literal objects and the literal objects within them using mustache? Being a neophyte at this I wondered if the following would work...
var data2 = {};
data2["collector"]={"sname":"Collector", "lname":"Collector", "V":[11,12,13,14,15]};
data2["storage"] ={"sname":"Storage", "lname":"Storage", "V":[21,22,23,24,25]};
data2["aux1"] ={"sname":"Aux1", "lname":"Loop High", "V":[31,32,33,34,35]};
data2["aux2"] ={"sname":"Aux2", "lname":"Loop Low", "V":[41,42,43,44,45]};
data2["aux3"] ={"sname":"Aux3", "lname":"Aux3", "V":[51,52,53,54,55]};
data2["aux4"] ={"sname":"Aux4", "lname":"Aux4", "V":[61,62,63,64,65]};
var T2 = "<table border='1'>" +
"{{#.}}<tr>" +
"{{#.}}" +
"<td>{{.}}</td>" +
"{{/.}}" +
"</tr>" +
"{{/.}}" +
"</table>"
html = Mustache.to_html(T2, data2);
but of course it doesn't. I get
{{/.}}
Since the goal was to use mustache, here's the final deal using mustache to expand the array.
I don't know if Jesse meant to put embedded literal objects in tables within table or not but that was not my goal. I deleted wrap and all from the function in this version as I either didn't need them or understand why they were there. I remain indebted to Jesse for this hint; I doubt I would have come up with anything so clever.
var getMustache = function(data, depth)
{
var r = "";
if (depth == 0)
{
r=r+"<tr>";
}
for(var d in data)
{
if(data.hasOwnProperty(d))
{
if(typeof data[d] =="object")
{
if (data[d].length) // is it an array?
{
var T = "{{#" + d + "}}<td>{{.}}</td>{{/" + d + "}}";
r += Mustache.to_html(T, data);
}
else
{
r += getMustache(data[d], depth+1);
}
}
else
{
r += "<td>" + data[d] + "</td>";
}
}
if (depth == 0)
{
r=r+"</tr>";
}
}
return r;
}
var T2 = "<table border='1'>" + getMustache(data2,0) + "</table>";
html = Mustache.to_html(T2, data2);
document.write(html);
Seems like you could just make a recursive function for this - mustache is pretty static, but recursion is perfect for looking up all the nodes in a deep object.
Untested hypothetical code:
var data2 = {};
data2["collector"]={"sname":"Collector", "lname":"Collector", "V":[11,12,13,14,15]};
data2["storage"] ={"sname":"Storage", "lname":"Storage", "V":[21,22,23,24,25]};
data2["aux1"] ={"sname":"Aux1", "lname":"Loop High", "V":[31,32,33,34,35]};
data2["aux2"] ={"sname":"Aux2", "lname":"Loop Low", "V":[41,42,43,44,45]};
data2["aux3"] ={"sname":"Aux3", "lname":"Aux3", "V":[51,52,53,54,55]};
data2["aux4"] ={"sname":"Aux4", "lname":"Aux4", "V":[61,62,63,64,65]};
var getMustache = function(data, wrap, all, depth){
var r = "";
var depth = depth || 0;
for(var d in data){
if(data.hasOwnProperty(d)){
r += "<" + wrap[depth] || all + ">";
if(data[d].length){
r += "{{#" + d + "}}";
r += getMustache(data[d], wrap, all, depth ++);
r += "{{/" + d + "}}";
} else {
r += "{{" + data[d] + "}}";
}
r += "</" + wrap[depth] || all + ">";
}
}
return r;
}
var T2 = "<table border='1'>" + getMustache(data2,['tr','td'],'span');
html = Mustache.to_html(T2, data2);
The following works. It doesn't use mustache facilities at all. I plan to change it so that it uses mustache's iteration on the array.
var getMustache = function(data, wrap, all, depth)
{
var r = "";
if (depth == 0)
{
r=r+"<tr>";
}
for(var d in data)
{
if(data.hasOwnProperty(d))
{
if(typeof data[d] =="object")
{
r += getMustache(data[d], wrap, all, depth+1);
}
else
{
r += "<td>" + data[d] + "</td>";
}
}
if (depth == 0)
{
r=r+"</tr>";
}
}
//alert("r=" + r);
return r;
}

Categories