I have an array in json, composed of three other arrays. One of those three arrays also has another array nested in it, and that array has a third array nested within it:
{
"items": [
{location: "Tiberius' Palace",
starting_line: 0,
line_text: "I command sylyns, in þe peyn of forfetur,",
duration: 1,
characters: {first_character:
{character: "Emperor", color: "660066"}
}
}
],
"directions": [],
"locations": []
}
I feed this json into d3 in a pretty standard way:
d3.json("MM_chart_test.json", function(error, json)
and then call to each of the three arrays:
var items = json.items;
var locations = json.locations;
var directions = json.stage_directions;
The problem I'm running into is that making these variable declarations results in the items variable dropping anything deeper than the characters declaration, so that the json looks like this:
{location: "Tiberius' Palace",
starting_line: 0,
line_text: "I command sylyns, in þe peyn of forfetur,",
duration: 1,
characters: {first_character:
null}
}
I haven't done anything beyond the variable declaration, and both of the other arrays work fine. It's obvious to me that the problem lies with declaring the variable, but I'm wondering what the best way is to do so without losing that two-deep information. Thank you.
Add quotes around the property names. As Sebastian Lorenzo said above it's invalid JSON.
{
"location":"Tiberius' Palace",
"starting_line":0,
"line_text":"I command sylyns, in þe peyn of forfetur,",
"duration":1,
"characters":{
"first_character":null
}
}
Related
I have a JSON data set as follows:
{
"content":[],
"layout":[],
"trail":[
{
"content":[
{
"type":"image",
"media":[
{
"type":"image/jpg",
"width":593,
"height":900,
"url":"https://live.staticflickr.com/65535/48208920877_e6b234d3ea_c_d.jpg",
"flickr":{
"flickr-post":"https://www.flickr.com/photos/riketrs/48208920877",
"flickr-album":"https://www.flickr.com/photos/riketrs/albums/72157709130951466"
}
}
]
},
{
"type":"image",
"media":[
{
"type":"image/jpg",
"width":1600,
"height":900,
"url":"https://live.staticflickr.com/2817/33807326532_91013ef6b1_h_d.jpg",
"flickr":{
"flickr-post":"https://www.flickr.com/photos/146758538#N03/33807326532",
"flickr-album":"https://www.flickr.com/photos/146758538#N03/albums/72157681438471236"
}
}
]
}
],
"colors":{
"c0":"#1e1e1d",
"c1":"#78736f",
"c2":"#b2a89f"
}
}
]
}
I would like to console.log the "url" key for each of the images shown here.
(https://live.staticflickr.com/65535/48208920877_e6b234d3ea_c_d.jpg and https://live.staticflickr.com/2817/33807326532_91013ef6b1_h_d.jpg)
I tried some code but I'm very new to JSON in general, I've looked at some other answers to do with JSON but I'm not quite sure how to achieve what I want.
JSFiddle: https://jsfiddle.net/fj6qveh1/1/
I appreciate all advice, including links to other answers that I potentially missed.
Thank you!
url is a property of an object. There can be many of these in a media array. (This data only shows one object per array.) media itself is an property of objects inside the content array.
Use map, and flatMap.
map to return the URL values from the objects in media, and flatMap to return a flat array of the nested arrays returned by map.
const data={content:[],layout:[],trail:[{content:[{type:"image",media:[{type:"image/jpg",width:593,height:900,url:"https://live.staticflickr.com/65535/48208920877_e6b234d3ea_c_d.jpg",flickr:{"flickr-post":"https://www.flickr.com/photos/riketrs/48208920877","flickr-album":"https://www.flickr.com/photos/riketrs/albums/72157709130951466"}}]},{type:"image",media:[{type:"image/jpg",width:1600,height:900,url:"https://live.staticflickr.com/2817/33807326532_91013ef6b1_h_d.jpg",flickr:{"flickr-post":"https://www.flickr.com/photos/146758538#N03/33807326532","flickr-album":"https://www.flickr.com/photos/146758538#N03/albums/72157681438471236"}},{type:"image/jpg",width:1600,height:900,url:"https://live.dummyimage.com/2817/dummy.jpg",flickr:{"flickr-post":"https://www.flickr.com/photos/146758538#N03/33807326532","flickr-album":"https://www.flickr.com/photos/146758538#N03/albums/72157681438471236"}}]}],colors:{c0:"#1e1e1d",c1:"#78736f",c2:"#b2a89f"}}]};
const content = data.trail[0].content;
const urls = content.flatMap(obj => {
return obj.media.map(inner => inner.url);
});
console.log(urls)
The easiest way is to use map function. Given that you are very new to programming (the solution has little to do with JSON itself, since the first step is to parse JSON string to a JavaScript object), it would be better if you try yourself. But you start with
let urls = trail["content"].map(x => x["media"][0]["url"])
for more about map function look here
There is a table in the table so for each table:
for(let i in trail){
var content = trail[i]["content"];
content.forEach(content => content.media.forEach(media => console.log(media.url)))
}
To access object properties, you can use a dot (.), and to access an array element, you use its index in square brackets ([]). So you just keep repeating these steps as necessary until you get to the content you're looking for.
Here's how that looks on a simplified version of your object, using the forEach method of arrays to apply a custom function to each item in the content array:
const json = getJson();
json.trail[0].content.forEach(item=>console.log(item.media[0].url));
function getJson(){
let obj = {
"trail": [{
"content": [
{ "media": [{ "url":"image #65535/48208920877_e6b234d3ea_c_d.jpg" }]},
{ "media": [{"url":"image #2817/33807326532_91013ef6b1_h_d.jpg"}]}
]
}]
};
return obj;
}
I am trying to edit the first entry in a array before it placed in another file.
This is it:
(["\"NAMES\":\"cs.js\"},[
I want to turn it into this:
([{"NAMES":"cs.js"},[
I'm using an online regex generator, but so far I've only managed to edit to this point with /.["[\]/ and substituting with ([{:
([{"NAMES\":\"cs.js\"},[
Any help given will be appreciated.
EDIT:
Here is some of the code:
var initialCourseArray = new Array()
initialCourseArray.push(["\"NAMES\":\"cs.js\"},[
{"COURSE_ID":"ENGL 1013"},
{"COURSE_ID":"FAH1"},
{"COURSE_ID":"USHG1"},
{"COURSE_ID":"TECH 1001"},
{"COURSE_ID":"COMS 1403"},
{"COURSE_ID":"COMS 1411"},
{"COURSE_ID":"ENGL 1023"},
{"COURSE_ID":"SS1"},
{"COURSE_ID":"MATH 2914"},
The stuff after is the rest of the values in the array and they do not look like this one so I'm not worried about them.
Second EDIT:
Since there is some confusion about the code that I honestly should have placed in here first, I am using a php file to retreive course data from a test database and then encoding it into JSON, formatting it, and then using fopen and fprintf to place it inside a javascript file. The part I'm giving you is what ends up inside the javascript file.
Third EDIT:
here is the code I am using to format the array. It is very messy because my leader keeps changing the format he wants the result to be in:
$row1 = "\"NAMES\"";
$colon = ":";
$row2 = "\"".$major.".js\"";
$major_name = $row1.$colon.$row2;
//The course data is already loaded into the table. This why I am using array_unshift to place the major_name inside.
array_unshift($major_array, $major_name);
array_push($major_array, "false");
$json_string = json_encode($major_array);
$re = "/.,/";
$subst = "},\r\n";
$json_string = preg_replace($re, $subst, $json_string);
$re2 = "/\,(?=[^.]*$)/";
$subst2 = ",[";
$json_string = preg_replace($re2, $subst2, $json_string, 1);
$first_string = "var initialCourseArray = new Array()";
$second_string = "initialCourseArray.push(";
$end_bracket = "]";
$end_parentheses =")";
There are several issues:
1. Don't manipulate JSON strings
You should never manipulate a string that is the result of json_encode, because you will very likely make the JSON text invalid, which is actually happening in your case.
So using this kind of statements:
$json_string = preg_replace($re, $subst, $json_string);
is asking for trouble. Once you have a $json_string, it should be final. Anything you want to happen to the structure must happen before you call json_encode.
Even if you just want to add line breaks inside a JSON string, don't do it that way. json_code provides a "pretty print" option which will do it for you:
json_encode(...., JSON_PRETTY_PRINT);
2. JavaScript does not have associative arrays
A second problem is that in JavaScript you cannot have something like
["NAMES":"cs.js" ...]
So json_encode will never generate anything like that. If you want named keys in JavaScript (like "NAMES"), you cannot define it as an array, but should define it as an object:
{"NAMES":"cs.js" ...}
json_encode will do that for you if you provide it the corresponding PHP structure (i.e. an associative array) and let it do its job without tampering.
3. Don't add "false"
It does not seem useful to add "false" as an element to the courses array. In JavaScript you can easily check how many elements there are in an array, so there is no need to put a kind of stop-sign at the end.
Anyway, if in JavaScript you refer to an element in an array that does not exist, you get undefined, which you can verify, much like verifying for the value "false".
I would strongly suggest to leave that out.
Suggested code
The PHP code you provided in your question could be replaced with this:
// Add the names element as a separate item next to the courses array,
// which we put in the "courses" property.
$major_array = array(
"names" => $major,
"courses" => $major_array
);
// Turn into JSON text with added line breaks and indentation:
$json_string = json_encode($major_array, JSON_PRETTY_PRINT);
// Don't touch the JSON text anymore, but output it:
echo "var initialCourse = $json_string;";
The output (JavaScript) would be something like:
var initialCourse = {
"names": "cs",
"courses": [
{
"COURSE_ID": "ENGL 1013"
},
{
"COURSE_ID": "FAH1"
},
{
"COURSE_ID": "USHG1"
},
{
"COURSE_ID": "TECH 1001"
},
{
"COURSE_ID": "COMS 1403"
},
{
"COURSE_ID": "COMS 1411"
},
{
"COURSE_ID": "ENGL 1023"
},
{
"COURSE_ID": "SS1"
},
{
"COURSE_ID": "MATH 2914"
}
]
};
As I mentioned above, this is an object structure, not an array structure, because JavaScript does not allow named keys in an array notation. If in JavaScript you need to iterate over the courses in the above structure, you would address the courses property (which is an array), like this:
for (var course of initialCourse.courses) {
console.log('course id: ' + course.COURSE_ID);
}
More concise structure
I must say it is a bit of an over-kill to have objects with just one property. This structure would be more concise and efficient:
var initialCourse = {
"names": "cs",
"courses": [
"ENGL 1013",
"FAH1",
"USHG1",
"TECH 1001",
"COMS 1403",
"COMS 1411",
"ENGL 1023",
"SS1",
"MATH 2914"
]
};
In JavaScript you would iterate over these courses like this:
for (var course of initialCourse.courses) {
console.log('course id: ' + course);
}
If this interests you, you should just add this line to your PHP code, before any of the PHP code I suggested above:
$major_array = array_map(function ($course) { return $course["COURSE_ID"]; }, $major_array);
If you just want to apply it to that line,
find /"?\\"/ and replace " will do it.
var jsonData = JSON.parse(pump_array);
var name_array = [];
var data_array = [];
for(var i=0;i<jsonData.pumps.length;i++)
{
data_array.push(data_array, pump_array.pumps[i].volume);
name_array.push(name_array, pump_array.pumps[i].iName);}
this is my javascript code. I am trying to parse out specific pieces of the following json array in order to place it into a graph using chart.js
var pump_array = {
"pumps":[
{
"id": 1,
"isPrimed":true,
"iName": "Whiskey",
"volume": 850,
"debug": "Test"
},
{
"id": 2,
"isPrimed":true,
"iName": "Vodka",
"volume": 900,
"debug": "Test"
}
]
}
There seem to be several things wrong here. First of all, you're calling JSON.parse on something that's not a string. It's a full-fledged Javascript object. There's no need to parse it; just use it.
Second of all, these two lines have an extra variable each:
data_array.push(data_array, pump_array.pumps[i].volume);
name_array.push(name_array, pump_array.pumps[i].iName);}
Presumably they should read:
data_array.push(pump_array.pumps[i].volume);
name_array.push(pump_array.pumps[i].iName);}
But even if you correct these problems, you still end up with a less-than-ideal data structure:
name_array; //=> ["Whiskey", "Vodka"]
data_array; //=> [850, 900]
Instead of a single, useful data structure, you end up with two different ones that are only useful via shared indices.
How about something like this instead?:
pump_array.pumps.reduce(function(soFar, pump) {
soFar[pump.iName] = pump.volume;
return soFar;
}, {});
//=> {Whiskey: 850, Vodka: 900}
To my eyes, that's a much more useful data structure.
As Iam new to javascript, I found handleBar.js can be used to template with dynamic data.
I worked on a sample which worked fine and the json structure was simple and straight forward.
(function()
{
var wtsource = $("#some-template").html();
var wtTemplate = Handlebars.compile(wtsource);
var data = { users: [
{url: "index.html", name: "Home" },
{url: "aboutus.html", name: "About Us"},
{url: "contact.html", name: "Contact"}
]};
Handlebars.registerHelper('iter', function(context, options) {
var fn = options.fn, inverse = options.inverse;
var ret = "";
if(context && context.length > 0) {
for(var i=0, j=context.length; i<j; i++) {
ret = ret + fn($.extend({}, context[i], { i: i, iPlus1: i + 1 }));
}
} else {
ret = inverse(this);
}
return ret;
});
var temp=wtTemplate(data);
$("#content").html(temp);
})();
<script id="some-template" type="text/x-handlebars-template">
{{#iter users}}
<li>
{{name}}
</li>
{{/iter}}
</script>
How to iterate a json with the below structure ? Please do suggest the possible way for iterating and creating the template for the below json structure
var newData = { "NEARBY_LIST": {
"100": {
"RestaurantID": 100,
"ParentRestaurantID": 0,
"RestaurantName": "Chennai Tiffin",
"listTime": [{
"startTime": "10:00",
"closeTime": "23:30"
} ]
},
"101": {
"RestaurantID": 101,
"ParentRestaurantID": 0,
"RestaurantName": "Biriyani Factory",
"listTime": [{
"startTime": "11:00",
"closeTime": "22:00"
}]
}
}
};
Accessing the properties of an object has nothing to do with Handlebars. If you dealing with JSON and you wish to access it in general bracket or dot notation, you must first parse the JSON into a JavaScript object using the JSON.parse() function.
After this is done, you may access the properties as follows.
var property = newData['NEARBY_LIST']['100'].RestaurantName; // "Chennai Tiffin"
Here is a fiddle to illustrate.
http://jsfiddle.net/qzm0cygu/2/
I'm not entirely sure what you mean, but if your question is how you can use/read the data in newData, try this:
newData = JSON.parse(newData); //parses the JSON into a JavaScript object
Then access the object like so:
newData.NEARBY_LIST //the object containing the array
newData.NEARBY_LIST[0] //the first item (key "100")
newData.NEARBY_LIST[1] //the second item (key "101")
newData.NEARBY_LIST[0][0] //the first field of the first item (key "RestaurantID", value "100")
newData.NEARBY_LIST[0][2] //the third field of the first item (key "RestaurantName", value "Chennai Tiffin")
newData.NEARBY_LIST[0][3][0] //the first field of the fourth field of the first item (key "startTime", value "11:00")
I hope this was what you were looking for.
EDIT: as Siddharth points out, the above structure does assume you have arrays. If you are not using arrays you can access the properties by using their names as if they're in an associative array (e.g. newData["NEARBY_LIST"]["100"]. The reason I say "properties" and "as if" is because technically JavaScript doesn't support associative arrays. Because they are technically properties you may also access them like newData.NEARBY_LIST (but I don't recommend that in this case as a property name may not start with a number, so you would have to use a mix of the different notations).
On that note, I would recommend using arrays because it makes so many things easier (length checks, for example), and there are practically no downsides.
EDIT2: also, I strongly recommend using the same camelcasing conventions throughout your code. The way you currently have it (with half your properties/variables starting with capitals (e.g. "RestaurantName", "RestaurantID") and the other half being in lowerCamelCase (e.g. "listTime", "startTime")) is just asking for people (you or colleagues) to make mistakes.
I have the following array:
var arry = [{title='Test'}, {title='Test2'}, {title='Test3'}];
I want to add a new property to each of the objects in the array. What is the fastest way of doing this?
for(var i = 0; i < arry.length; i++)
{
arry[i].prop = "value";
}
Given no further information: hands down and String manipulation.
Before every occurrence of }you insert foo='bar'
I feel like mentioning this is a terrible solution and if the structure of the array is not 100% rigid it will explode by the next update. Anyway it's a nice example to see what's happening "under the hood"
However in order to get a valid JSON String you have to enclose keys and string values with double qoutes.
Anyway I recommend you to get a JSONParser and start working with objects then you have a more robust solution e.g. Matthew posted it.
And here's the example of valid JSON
[
{
"title": "Test"
},
{
"title2": "Test2"
},
{
"title3": "Test3"
}
]
http://jsonlint.com/
Here's an example of some valid JSON:
[
{
"title1": "hey, this is test one"
},
{
"title2": "hi, test two"
},
{
"title3": "what's up, test three"
}
]
What you posted wasn't JSON.
This answer may help you: https://stackoverflow.com/a/617051/507629
To add something to an array you can just use .push() method, for example:
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi");
Learn more about .push here.