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.
Related
I am trying to make a messenger bot that can create buttons based on a number I enter. The code looks like this:
let messageData = {
"attachment": {
"type": "template",
"payload": {
"template_type": "button",
"text": text[1],
"buttons":[]
}
}
}
The part that says "buttons":[] is where I want to add buttons (inside the []) according to this format:
{
"type":"postback",
"title":"button" + i //where i is the button number,
"payload":"button" + i
}
How would I go about doing this?
For your example you can do this:
messageData.attachment.payload.buttons.push(obj)
the . accesses the object's key, which can also be done this way messageData['attachment']
The difference between
messageData.attachment
and
messageData['attachment']
is that the second one can take a variable instead of a string, e.g.
var use_key = 'attachment';
messageData[use_key];
will access the same as the other two above.
JSON is just short for JavaScript Object Notation. And you make it exactly like your second example:
{
"type":"postback",
"title":"button" + i //where i is the button number,
"payload":"button" + i
}
You can assign it to a variable to pass it into the push, or just exactly as it is. Not much different from a string or number. Don't let all the extra information scare you.
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
}
}
I have a casperjs script which iterates over a list of pages and extracts data.
On the other hand I have a csv file with 2 fields 'ean' 'ref' which I parse with Papa.parse. The output is an object. I am looking for a solution to query an javascript object (the output from Papa.parse) for the 'ref' field and extract the 'ean'. I thought .filter() is what i was looking for but that can only search for a predefined value in the callback function.
function cd(element) {
return element == '123';
}
var b = c.filter(cd);
The problem hear is 1. It returns an empty array and 2. even if it would work I need to change the value with every call since I want to find the ean value for any given ref.
function cd(element,ref) {
return element == ref;
}
This is the data I need to search
"data": [
{
"ean": "654321",
"ref": "123"
},
{
"ean": "1234567",
"ref": "124"
}
]
I hope I made myself more clear. Thank you in advance
I used https://lodash.com/docs#where
Does exactly what i want
var a = _.where(array,{'ref' : 'value i am looking for'});
result is an array from where I can extract the value of the ean field.
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.
Given a JSON string as this:
{
"__ENTITIES": [
{
"__KEY": "196",
"__STAMP": 1,
"ID": 196,
"firstName": "a",
"middleName": "b",
"lastName": "c",
"ContactType": {},
"addressCollection": {
"__deferred": {
"uri": "/rest/Contact(196)/addressCollection?$expand=addressCollection"
}
},
"__ERROR": [
{
"message": "Cannot save related entity of attribute \"ContactType\" for the entity of datastore class \"Contact\"",
"componentSignature": "dbmg",
"errCode": 1537
}
]
}
]
}
Is there a method to get just the __ERROR record, I know I can use
var mydata = json.parse(mydata) and then find it from the mydata object. But I was hoping there was a method to only return the ERROR field something like
json.parse(mydata, "__ERROR") and that gets only the information in the __ERROR field without turning the whole JSON string into an object
"Is there a method to get just the __ERROR record, I know I can use var mydata = json.parse(mydata) ... But I was hoping there was ... something like json.parse(mydata, "__ERROR")"
There may be libraries that do this, but nothing built in. You need to write code that targets the data you want.
The closest you'll get will be to pass a reviver function to JSON.parse.
var errors = [];
var mydata = JSON.parse(mydata, function(key, val) {
if (key === "__ERROR")
errors.push(val);
return val
});
without turning the whole json string into an object
That's hardly possible, you would need some kind of lazy evaluation for that which is not suitable with JS. Also, you would need to write your own parser for that which would be reasonable slower than native JSON.parse.
Is there a method to get just the __ERROR record
Not that I know. Also, this is an unusual task to walk the whole object tree looking for the first property with that name. Better access __ENTITIES[0].__ERROR[0] explicitly.
If such a function existed, it would have to parse the whole thing anyway, to find the key you're looking for.
Just parse it first, then get the key you want:
var mydata = JSON.parse(mydata);
var errorObj = mydata.__ENTITIES[0].__ERROR[0];
If you want, you may create your own function:
function parseAndExtract(json, key) {
var parsed = JSON.parse(json);
return parsed[key];
}