I'm loading an external JSON file into javascript, the JSON file looks like this:
[
{
"name":"Apple",
"year":8,
"records_lost":12367232
},
{
"name":"178.com",
"year":7,
"records_lost":10000000
},
{
"name":"Accendo Insurance Co. ",
"year":7,
"records_lost":175350
}
]
Eventually, I want to access the data via a Javascript object like this (don't mind the syntax). The point is that name will be a parent with its own meta-data.
"Apple":
"year":8,
"records_lost":12367232
"178.com":
"year":7,
"records_lost":10000000
This is the code I've already written for this part, which doesn't make name parent yet and only saves the last row of the JSON file into the array (+= instead of = would fix this, but delivers ugly values, obviously).
function initJSON() {
loadJSON(function(response) {
var JSONParse = JSON.parse(response);
var i;
for (i in JSONParse) {
JSONdata.name.i = JSONParse[i].name;
JSONdata.year = JSONParse[i].year;
JSONdata.recl = JSONParse[i].records_lost;
}
});
}
initJSON();
Thanks in forward.
Try utilizing Array.prototype.map() , delete operator
var data = [{
"name": "Apple",
"year": 8,
"records_lost": 12367232
}, {
"name": "178.com",
"year": 7,
"records_lost": 10000000
}, {
"name": "Accendo Insurance Co. ",
"year": 7,
"records_lost": 175350
}];
var res = data.map(function(val, key) {
var obj = {};
obj[val.name] = val;
delete obj[val.name].name;
return obj
});
document.getElementsByTagName("pre")[0].textContent = JSON.stringify(res, null, 4);
<pre></pre>
it should be :
var i;
for (i in JSONParse) {
JSONdata.name = i.name;
JSONdata.year = i.year;
JSONdata.recl = i.records_lost;
}
unless your loop was different:
var i;
for (i = 0; i < JSONParse.length; i++) {
JSONdata.name = JSONParse[i].name;
JSONdata.year = JSONParse[i].year;
JSONdata.recl = JSONParse[i].records_lost;
}
Related
How to convert a string to JSON with javascript or jQuery? I've been thinking all day, but I do not get a good idea.
This task is to dynamically create the treeview in the client side (ASP.Net). My idea is to convert the string to an object and convert to JSON type. (String -> object -> JSON) I tried, but the day is gone. It is difficult to construct 2 more depth like A->a3->a31.
String is
var sString = "A//a1,A//a2,A//a3//a31,A//a3//a32,B,C//c1,C//c2";
and JSON format is
{
"title": "A",
"key": "1",
"folder": true,
"children": [{
"title": "a1",
"key": "2"
}, {
"title": "a2",
"key": "3"
}, {
"title": "a3",
"key": "4",
"folder": true,
"children": [{
"title": "a31",
"key": "5"
}...
}]
}
(This is fancytreeview plugin)
‘//‘ is depth and ‘,’ is split.
Please help me..
Edit)
I want to turn ‘sString’ to JSON format.. but It’s ok just JSON type string.
Please understand that my sentence is strange because my native language is not English.
Edit2)
oh.. I want to convert the string to an object and then convert it back to JSON format. I do not have the confidence to convert that string into JSON format right away. Because there are more than 8000 variants. If It’s can, let me know how.
I believe this can be done without recursion:
var string = "A//a1,A//a2,A//a3//a31,A//a3//a32,B,C//c1,C//c2";
// Take all the roots
var roots = string.split(',');
// We will attach it to every node and keep it incrementing
var key = 1;
// The final result will be in this object
var result = [];
// Loop through to found roots
roots.forEach(function(root) {
// Take all the children
var items = root.split('//');
var parent = result;
// Loop through the available children
items.forEach(function(item, i) {
// Find if the current item exists in the tree
var child = getChild(parent, item);
if (!child) {
child = {
title: item,
key: key++
}
// This will ensure that the current node is a folder only
// if there are more children
if (i < items.length - 1) {
child.folder = true;
child.children = [];
}
// Attach this node to parent
parent.push(child);
}
parent = child.children;
});
});
console.log(result);
// Utility function to find a node in a collection of nodes by title
function getChild(parent, title) {
for (var i = 0; i < parent.length; i++) {
if (parent[i].title === title) {
return parent[i];
}
}
}
This is the draft code which came in my mind at first. I believe it can be improved further in terms of complexity.
var key = 1; // keys start at 1
let addPaths = (root, paths) => {
if (!paths || paths.length == 0)
return;
let path = paths.shift();
//add nodes for the current path
addNodes(root, path.split('//'));
// keep going until all paths have been processed
addPaths(root, paths);
};
let addNodes = (root, nodeList) => {
if (!nodeList || nodeList.length == 0)
return;
let title = nodeList.shift();
// find node under root with matching title
let isRootNode = Array.isArray(root);
node = (isRootNode ? root : root.children || []).find((node) => {
return node.title == title;
});
if (!node){
node = {
title: title,
key: key++
}
// are we at root of object?
if (isRootNode)
root.push(node);
else
{
if (!root.children)
root.children = [];
root.children.push(node);
root.folder = true;
}
}
addNodes(node, nodeList);
};
let parse = (string) => {
let object = [];
let nodes = string.split(',');
addPaths(object, nodes);
return object
};
console.log(JSON.stringify(parse("A//a1,A//a2,A//a3//a31,A//a3//a32,B,C//c1,C//c2"), null, 2));
Which results in:
[
{
"title": "A",
"key": 1,
"children": [
{
"title": "a1",
"key": 2
},
{
"title": "a2",
"key": 3
},
{
"title": "a3",
"key": 4,
"children": [
{
"title": "a31",
"key": 5
},
{
"title": "a32",
"key": 6
}
],
"folder": true
}
],
"folder": true
},
{
"title": "B",
"key": 7
},
{
"title": "C",
"key": 8,
"children": [
{
"title": "c1",
"key": 9
},
{
"title": "c2",
"key": 10
}
],
"folder": true
}
]
Try below code. I have used associative array to store already processed folder for faster lookup.
I hope it helps you.
var sString = "A//a1,A//a2,A//a3//a31,A//a3//a32,B,C//c1,C//c2";
var sArr = sString.split(","); // We will split it by comma so that we can iterate through its items.
var output = []; // Final result will be stored here.
var hash = {}; // It used to keep track of itemObjectect's position for faster lookup.
var counter = 1; // Its value will be used to assign to key;
for(var i = 0; i < sArr.length; i++){
var items = sArr[i].split("//");
var itemObject = {}; // Object to store value of each item.
var parentItemObject = {}; // It will refer to current parentObject during iteration.
for(var j = 0; j < items.length; j++){
// Check if item is already processed and stored in hash map.
if(hash.hasOwnProperty(items[j])){
// Check if parent Object value is empty then we will fetch it from hash directly.
if(isEmpty(parentItemObject)){
parentItemObject = output[hash[items[j]]];
}
else{
// It is parent element but is child of another element. Then we will fetch it from it's children array.
if(typeof parentItemObject.children !== "undefined"){
parentItemObject = parentItemObject.children[hash[items[j]]];
}
}
continue;
}
itemObject.title = items[j];
itemObject.key = counter++;
// Check if it is a folder item.
if(j != items.length -1){
itemObject.folder = true;
itemObject.children = [];
if(isEmpty(parentItemObject)){
parentItemObject = itemObject;
hash[itemObject.title] = output.length;
output.push(itemObject);
}
else{
if(typeof parentItemObject.children !== "undefined"){
hash[itemObject.title] = parentItemObject.children.length;
parentItemObject.children.push(itemObject);
}
parentItemObject = itemObject;
}
}
else{
if(isEmpty(parentItemObject)){
parentItemObject = itemObject;
hash[itemObject.title] = output.length;
output.push(itemObject);
}
if(typeof parentItemObject.children !== "undefined"){
hash[itemObject.title] = parentItemObject.children.length;
parentItemObject.children.push(itemObject);
}
}
itemObject = {};
}
//console.log(items);
}
function isEmpty(itemObject) {
return Object.keys(itemObject).length === 0;
}
//console.log(hash);
console.log(JSON.stringify(output,null,2));
Update: Fixed mistakes in example code. Turned out my problem was caused by an additional 'records' in var jsonVar = jsonVar.concat(results.records);
How can I concat JSON objects in a loop? I can concat 2 JSON objects like this:
var json1 = {
"records": [{
"id": 28100988,
"work_text_reviews_count": 13,
"average_rating": "3.10"
}, {
"id": 10280687,
"work_text_reviews_count": 80,
"average_rating": "3.87"
}]
}
var json2 = {
"records": [{
"id": 16135639,
"work_text_reviews_count": 0,
"average_rating": "0.00"
}, {
"id": 17978337,
"work_text_reviews_count": 2414,
"average_rating": "3.76"
}, {
"id": 360721218,
"work_text_reviews_count": 4924,
"average_rating": "3.98"
}]
}
var json3 = json1.records.concat(json2.records);
To add a 3rd JSON object I know I can just add .concat(json3.records)
but how can I dynamically concatenate JSON objects in a loop?
Example:
Say values.length = 5, this means 5 JSON objects need to be concatenated.
for (var i=0; i<values.length ; i++) {
response= UrlFetchApp.fetch(url);
Utilities.sleep(1000);
var results = JSON.parse(response);
// this works now (had a typo here)
var jsonVar = jsonVar.concat(results.records);
}
You could do something like:
var jsonVar = [];
for (var i=0; i<values.length ; i++) {
results= UrlFetchApp.fetch(url);
Utilities.sleep(1000);
var results = JSON.parse(response);
jsonVar = jsonVar.concat(results.records);
}
But I am not sure if this would work because UrlFetchApp.fetch() seems to be asynchronous. This means the response is not guaranteed to be initialized to correct value if it takes more than 1000ms
A JSON object is a Javascript object. You can dynamically set the object name
for (var i=0; i<values.length ; i++) {
json[i].records.concat(json[i + 1].records)
}
I'm getting an XML and parsing it, saving it to array, the problems is that I get objects in this order:
temp1.ID = 15
temp1.name = "Dan"
temp1.phone = "32332"
temp2.ID = 12
temp2.name = "Test"
temp2.phone = 53463
temp3.ID = 2
temp3.name = "Tom"
temp3.phone = 12443
.
.
.
.
Object - its an objects that I get inside a loop while parsing XML
What I try is to save them in the same order I started to read them : Array: [temp1,temp2,temp3]
But The result of the next function is : Array: [temp3,temp2,temp1]
the function:
this.mytempect = [];
for (var i = 0; i < xml.length; i++) {
var temp = {};
temp.ID = parseXmlByTag(xml[i], "ID");
temp.name = parseXmlByTag(xml[i], "name");
temp.phone = parseXmlByTag(xml[i], "phone");
if (this.mytempect [temp .ID] == null) {
this.mytempect [temp .ID] = [];
}
this.mytempect [temp .ID].push(obj);
}
Before I save each object I check if I need to create for him a new Key or to add to existing one, in the end I get something like this:
I need to save the order in which I'm getting them so I'll save them in the order I entered them
If I understand your question here's what I think you should be doing. You seem to be confusing objects and arrays: mytempect needs to be an object if you want to store arrays against a key set by the ID.
Following your example, objects with the same key are assigned to the same array (identified by that key in the object) in the order in which they are read.
// create an object, not an array
this.mytempect = {};
for (var i = 0; i < arr.length; i++) {
var temp = {};
temp.ID = arr[i].ID;
temp.name = arr[i].name;
temp.phone = arr[i].phone;
// Don't check for null here because `this.mytempect[temp.ID]` might not exist
if (!this.mytempect[temp.ID]) {
this.mytempect[temp.ID] = [];
}
this.mytempect[temp.ID].push(temp);
}
DEMO
The demo produces an object with one object in an array under key 15, two under 12 and one under 2:
{
"2": [
{
"ID": 2,
"name": "Tom",
"phone": 12443
}
],
"12": [
{
"ID": 12,
"name": "Test",
"phone": 53463
},
{
"ID": 12,
"name": "Test",
"phone": 53462
}
],
"15": [
{
"ID": 15,
"name": "Dan",
"phone": "32332"
}
]
}
Note: you can't order the object in any way.
Perhaps you're looking for something like this
var mytempect = [],
dict = {},
i,
tmp;
for (i = 0; i < xml.length; ++i) {
tmp = {
ID: parseXmlByTag(xml[i], "ID"),
name: parseXmlByTag(xml[i], "name"),
phone: parseXmlByTag(xml[i], "phone")
};
if (!(tmp.ID in dict)) {
mytempect.push(dict[tmp.ID] = []);
}
dict[tmp.ID].push(tmp); // use fact Objects ByRef to add item
}
dict = null; // cleanup
The Array mytempect will now have indices 0, 1, 2, etc containing Arrays of all Objects which have the same ID. With your sample data you will get
mytempect[0][0].ID === 15;
mytempect[1][0].ID === 12;
mytempect[2][0].ID === 2;
I have json data like this.
[{"data":"85"},{"data":"83"},{"data":"75"},{"data":"87"},{"data":"86"},{"data":"0"},{"data":"84"}].
I wanted to remove the "data": and curly brackets.
I wanted the output to be like this.
[85,83,75,87,86,0,84]
Someone please help me on converting it to like that.
You tagged your question with jQuery, so heres an answer using it:
var input = [{ "data": "85" }, { "data": "83" }, { "data": "75" }, { "data": "87" }, { "data": "86" }, { "data": "0" }, { "data": "84" }];
var output = $.map(input, function (e) { return e.data; });
var newArray = [];
jsonData.forEach(function(i) {
newArray.push(i.data);
});
Where jsonData is the name of the variable storing your JSON data.
Loop through the array and extract data value like this
var obj= [{"data":"85"},{"data":"83"},{"data":"75"},{"data":"87"},{"data":"86"},{"data":"0"},{"data":"84"}];
var arr = [];
for ( var i = 0; i < obj.length;i++){
arr.push(obj[i].data);
}
Please check the following code.
var myMessage = [{"data":"85"},{"data":"83"},{"data":"75"},{"data":"87"},{"data":"86"},{"data":"0"},{"data":"84"}];
var obj2 = eval(myMessage);
var myArray = new Array();
for(var i in obj2){
myArray[i] = obj2[i].data;
}
console.log(myArray);
Cheers Subh
var msg = '[{"data":"85"},{"data":"83"},{"data":"75"},{"data":"87"},{"data":"86"},{"data":"0"},{"data":"84"}]';
var msgObject = JSON.parse(msg);
var output = new Array();
for (var i = 0; i < msgObject.length; i++) {
output.push(msgObject[i].data);
}
alert(JSON.stringify(outputObject));
I want to add javascript array values into JSON values object. The other element is also replaced my element like recipients, subject, message. I got Json like:
Below is my code.
var BODY = {
"recipients": {
"values": [
]
},
"subject": title,
"body": message
}
var values = [];
for (var ln = 0; ln < names.length; ln++) {
var item1 = {
"person": {
"_path": "/people/"+names[ln],
},
};
values.push(item1);
}
BODY = JSON.stringify({values: values});
alert(BODY);
I think you want to make objects from array and combine it with an old object (BODY.recipients.values), if it's then you may do it using $.extent (because you are using jQuery/tagged) method after prepare the object from array
var BODY = {
"recipients": {
"values": []
},
"subject": 'TitleOfSubject',
"body": 'This is the message body.'
}
var values = [],
names = ['sheikh', 'muhammed', 'Answer', 'Uddin', 'Heera']; // for testing
for (var ln = 0; ln < names.length; ln++) {
var item1 = {
"person": { "_path": "/people/"+names[ln] }
};
values.push(item1);
}
// Now merge with BODY
$.extend(BODY.recipients.values, values);
DEMO.
If you want to stick with the way you're populating the values array,
you can then assign this array like so:
BODY.values = values;
after the loop.
It should look like this:
var BODY = {
"recipients": {
"values": [
]
},
"subject": title,
"body": message
}
var values = [];
for (var ln = 0; ln < names.length; ln++) {
var item1 = {
"person": {
"_path": "/people/"+names[ln],
},
};
values.push(item1);
}
BODY.values = values;
alert(BODY);
JSON.stringify() will be useful once you pass it as parameter for an AJAX call.
Remember: the values array in your BODY object is different from the var values = [].
You must assign that outer values[] to BODY.values. This is one of the good things about OOP.
You can directly access BODY.values:
for (var ln = 0; ln < names.length; ln++) {
var item1 = {
"person": {
"_path": "/people/"+names[ln],
},
};
BODY.values.push(item1);
}
var arr = [ 'a', 'b', 'c'];
arr.push('d'); // insert as last item