Parsing JSON into clean HTML view - html

I am working on a JSON code. EG:
{"resultSet":{"arrival":[{"feet":null,"departed":false,"scheduled":1460553672000,"
shortSign":"34 To Oregon City TC","detoured":false,"tripID":"6317022","dir":0,
"blockID":3402,"route":34,"piece":"1","fullSign":"34 River Rd to Oregon City TC",
"id":"6317022_22872_13","vehicleID":null,"locid":10,"newTrip":false,
"status":"scheduled"}],"queryTime":1460522014873,
"location":[{"lng":-122.603190086107,"passengerCode":"E","id":10,
"dir":"Southbound","lat":45.3847203071942,"desc":"Abernethy & Barclay"}]}}
and I need to convert it into a HTML Table view.
But the JSON data may not always appear the same structure. It can be different like this.
{"resultSet":{"arrival":[{"feet":50907,"inCongestion":false,"departed":false,
"scheduled":1460524334000,"loadPercentage":0,"shortSign":"78 To Beaverton TC",
"estimated":1460524334000,"detoured":false,"tripID":"6322386","dir":1,
"blockID":7672,"route":78,"piece":"1","fullSign":"78 Beaverton TC",
"id":"6322386_79934_12","vehicleID":"2918","locid":1233,"newTrip":false,
"status":"estimated"},{"feet":null,"departed":false,"scheduled":1460528004000,
"shortSign":"78 To Beaverton TC","detoured":false,"tripID":"6322387","dir":1,
"blockID":7867,"route":78,"piece":"1","fullSign":"78 Beaverton TC",
"id":"6322387_83604_12","vehicleID":null,"locid":1233,"newTrip":false,
"status":"scheduled"},{"feet":null,"departed":false,"scheduled":1460557107000,
"shortSign":"37 To Tualatin P&R","detoured":false,"tripID":"6317319","dir":0,
"blockID":3767,"route":37,"piece":"1",
"fullSign":"37 Lake Grove to Tualatin Park & Ride","id":"6317319_26307_13",
"vehicleID":null,"locid":1233,"newTrip":false,"status":"scheduled"}],
"queryTime":1460522323801,"location":[{"lng":-122.697651868185,
"passengerCode":"E","id":1233,"dir":"Westbound","lat":45.423844983607,
"desc":"Country Club & Wembley Park"}]}}
How would I be able to achieve the result in HTML Table view?

I am afraid this is anything BUT elegant but I did get the solution in the end. ;-)
Maybe you can use some ideas ... (like collecting the attributes with function getkeys() ...)
// first test case:
var dat={"resultSet":{"arrival":[{"feet":50907,"inCongestion":false,"departed":false,
"scheduled":1460524334000,"loadPercentage":0,"shortSign":"78 To Beaverton TC",
"estimated":1460524334000,"detoured":false,"tripID":"6322386","dir":1,
"blockID":7672,"route":78,"piece":"1","fullSign":"78 Beaverton TC",
"id":"6322386_79934_12","vehicleID":"2918","locid":1233,"newTrip":false,
"status":"estimated"},{"feet":null,"departed":false,"scheduled":1460528004000,
"shortSign":"78 To Beaverton TC","detoured":false,"tripID":"6322387","dir":1,
"blockID":7867,"route":78,"piece":"1","fullSign":"78 Beaverton TC",
"id":"6322387_83604_12","vehicleID":null,"locid":1233,"newTrip":false,
"status":"scheduled"},{"feet":null,"departed":false,"scheduled":1460557107000,
"shortSign":"37 To Tualatin P&R","detoured":false,"tripID":"6317319","dir":0,
"blockID":3767,"route":37,"piece":"1",
"fullSign":"37 Lake Grove to Tualatin Park & Ride","id":"6317319_26307_13",
"vehicleID":null,"locid":1233,"newTrip":false,"status":"scheduled"}],
"queryTime":1460522323801,"location":[{"lng":-122.697651868185,
"passengerCode":"E","id":1233,"dir":"Westbound","lat":45.423844983607,
"desc":"Country Club & Wembley Park"}]}};
// second test case with missing "arrival" sub-array:
var dat ={"resultSet":{"queryTime":1460959167994,"location":[{"lng":-122.79683594921,
"pas‌​sengerCode":"E","id":997,"dir":"Southbound",
"lat":45.506252040801,"desc":"SW Cedar Hills & Berkshire"}]}};
var maxr=0;
function getkeys(arr) { var keys={};
// the following "if ... else" was added to deal with missing sub-arrays:
if (arr) {arr.forEach(function(o,i){for (a in o) keys[a]=1;});
var ret=Object.keys(keys); if ((ret.len=arr.length)>maxr) maxr=ret.len;
} else ret=[];
// ret.len is the number of rows found in the array arr
// and should not be confused with ret.length (=the length of ret)
return ret;
}
var rs=dat.resultSet,
okeys={rs:getkeys([rs]),arrival:getkeys(rs.arrival),location:getkeys(rs.location)};
// first title row
var r=[okeys.rs.map(function(rk){
return '<th'+(okeys[rk]?' colspan="'+okeys[rk].length+'"':'')+'>'+rk+'</th>';}).join('')],
tmp=[];
// second title row
okeys.rs.forEach(function(rk){
if (okeys[rk]) [].push.apply(tmp,okeys[rk]); // push a group of columns
else tmp.push(rk); // push a single column into array tmp
});
r.push('<td>'+tmp.join('</td><td>')+'</td>');
// data rows
for (i=0;i<maxr;i++){ tmp=[];
okeys.rs.forEach(function(rk){var ok=okeys[rk],l,td;
if (ok) { l=ok.len; td='<td'+(maxr>l && l==i+1?' rowspan="'+(maxr-i)+'">':'>');
if (i<l) [].push.apply(tmp,ok.map(function(k){return td+(rs[rk][i][k]||'')+'</td>';}));
}
else if (!i) tmp.push('<td rowspan="'+maxr+'">'+rs[rk]+'</td>'); // push a single column into array tmp
});
r.push(tmp.join(''));
}
// output onto page
document.getElementById("out").innerHTML=
'<table><tr>'+r.join('</tr>\n<tr>')+'</tr></table>';
th,td {border: solid 1px}
<div id="out"></div>
Edit:
I just added an if ... else block in the getkeys() function to deal with cases when not all of the sub-arrays, as defined in the okeys-object, are present in dat. In the latest test case the sub-array "arrival" was missing.

Related

SSIS Script howto append text to end of each row in flat file?

I currently have a flat file with around 1million rows.
I need to add a text string to the end of each row in the file.
I've been trying to adapt the following code but not having any success :-
public void Main()
{
// TODO: Add your code here
var lines = System.IO.File.ReadAllLines(#"E:\SSISSource\Source\Source.txt");
foreach (string item in lines)
{
var str = item.Replace("\n", "~20221214\n");
var subitems = str.Split('\n');
foreach (var subitem in subitems)
{
// write the data back to the file
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
I can't seem to get the code to recognise the carriage return "\n" & am not sure howto write the row back to the file to replace the existing rather than add a new row. Or is the above code sending me down a rabbit hole & there is an easier method ??
Many thanks for any pointers &/or assistance.
Read all lines is likely getting rid of the \n in each record. So your replace won't work.
Simply append your string and use #billinKC's solution otherwise.
BONUS:
I think DateTime.Now.ToString("yyyyMMdd"); is what you are trying to append to each line
Thanks #billinKC & #KeithL
KeithL you were correct in that the \n was stripped off. So I used a slightly amended version of #billinKC's code to get what I wanted :-
string origFile = #"E:\SSISSource\Source\Sourcetxt";
string fixedFile = #"E:\SSISSource\Source\Source.fixed.txt";
// Make a blank file
System.IO.File.WriteAllText(fixedFile, "");
var lines = System.IO.File.ReadAllLines(#"E:\SSISSource\Source\Source.txt");
foreach (string item in lines)
{
var str = item + "~20221214\n";
System.IO.File.AppendAllText(fixedFile, str);
}
As an aside KeithL - thanks for the DateTime code however the text that I am appending is obtained from a header row in the source file which is being read into a variable in an earlier step.
I read your code as
For each line in the file, replace the existing newline character with ~20221214 newline
At that point, the value of str is what you need, just write that! Instead, you split based on the new line which gets you an array of values which could be fine but why do the extra operations?
string origFile = #"E:\SSISSource\Source\Sourcetxt";
string fixedFile = #"E:\SSISSource\Source\Source.fixed.txt";
// Make a blank file
System.IO.File.WriteAllText(fixedFile, "");
var lines = System.IO.File.ReadAllLines(#"E:\SSISSource\Source\Source.txt");
foreach (string item in lines)
{
var str = item.Replace("\n", "~20221214\n");
System.IO.File.AppendAllText(fixedFile, str);
}
Something like this ought to be what you're looking for.

Example: Tablesorter Output widget difference between download and popup special characters

I am using the output widget of tablesorter to get my table as csv (for excel). The table has no problems with special chars. If I export the data as output its all fine. If I use download option special characters like & are shown as & (seen in Notepad++) so Excel decides to separate it as there is a ;
Any help?
UPDATE:
http://jsfiddle.net/abkNM/6503/
Thanks!
Ok, I ended up adding a new callback function output_formatContent*. Use it as follows (demo):
output_formatContent: function (config, widgetOptions, data) {
// data.isHeader (boolean) = true if processing a header cell
// data.$cell = jQuery object of the cell currently being processed
// data.content = processed cell content
// (spaces trimmed, quotes added/replaced, etc)
// **********
// use data.$cell.html() to get the original cell content
return data.content.replace(/&/g, '&');
}
if you want to replace all HTML codes, then check out Mathias Bynens he which would work as follows:
output_formatContent : function( c, wo, data ) {
// replace all HTML shortcut codes
// (e.g. 'foo © bar ≠ baz 𝌆 qux' becomes 'foo © bar ≠ baz 𝌆 qux' )
return he.decode( data.content );
}
* Note: the new output widget callback is currently only available in the master branch of the tablesorter repository. It will be included in the next update.

actionscript remove (concat?) sub-arrays

I have multiple sub-arrays in one huge array - MasterArray- meaning that the sub-arrays are already INSIDE the MasterArray. I would like to "fuse" all of those sub-arrays - to remove those [ ] square brackets.
I would like to avoid the "concat" method because the arrays are already inside the MasterArray. Is there a command/method how to do this?
Thank you.
var englandCities:Array = [London, Manchester, Leeds];
var franceCities:Array = [Paris, Orleans, Avignon];
var europeanCities:Array = [englandCities, franceCities];
I would like to point let's say...to "London" nested in the europeanCities array somehow.
After I try to trace it, it gives me "englandCities", which makes sense.
trace(europeanCities[0]);
// displays "englandCities"
// how can I make it display "London" ?
How can I make the europeanCities array to display "London" ?
I NEED TO REMOVE THOSE SQUARE BRACES from the "europeanCities" array WITHOUT using the concat() thingie...
OKAY let me rephrase this a bit. My master array:
var europeanCities:Array = [englandCities, franceCities];
equals to
[[London, Manchester, Leeds], [Paris, Orleans, Avignon]];
am I right? And now, how to remove the inner brackets in order to get something like this:
[London, Manchester, Leeds, Paris, Orleans, Avignon];
And please, keep in mind, that the array is much longer than englandCities and frenchCities....there are like...30 different Cities.
You can concat those together easily, and it really is the simplest option:
var englandCities:Array = ["London", "Manchester", "Leeds"];
var frenchCities:Array = ["Paris", "Orleans", "Avignon"];
var masterArray:Array = [englandCities, frenchCities];
var europeanCities:Array = new Array();
for each(var country:Array in masterArray) {
europeanCities = europeanCities.concat(country);
}
trace(europeanCities); // London,Manchester,Leeds,Paris,Orleans,Avignon
I'm not sure I understand your reason for avoiding concat for this, unless the issue is it that you don't want to duplicate the values. (So modifying englandCities[0] will also modify europeanCities[0].)
If your cities are Objects rather than primitive Strings, a concatenated Array will work fine. If they are primitives though, there's no way to do this with an Array. You could however write a function to provide similar behaviour like this:
var englandCities:Array = ["London", "Manchester", "Leeds"];
var frenchCities:Array = ["Paris", "Orleans", "Avignon"];
var allCities:Array = [englandCities, frenchCities];
function europeanCities(id:int):String {
var cityID:uint = 0;
while (id > allCities[cityID].length - 1) {
id -= allCities[cityID].length;
cityID++;
}
return allCities[cityID][id];
}
trace (europeanCities(0)); // London
trace (europeanCities(5)); // Avignon
Create an empty array, then traverse the masterArray taking any sub-arrays, and do a concat() for your new array. This will make you another array that's flat, without disturbing master array.
I just write this here because it is possible.
If you insist on not using concat here is one bad solution:
// join elements into a comma delimited string
var s: String = europeanCities.join(',');
// Split the string with delimiter as commas
europeanCities = s.split(',');
Since the subarray elements automatically will be joined with ',' regardless of join delimiter and our join delimiter is already ',' this will work.
But this solution is cpu intensive and not optimal.

Octave vectorize strsplit return value into separate variables

I have a file with a list of records which I parse one line at a time. Each record is newline delimited and each value is space delimited. This is just a simplified example, but it has a similar structure to the real data.
Bob blue pizza
Sally red sushi
The first value is a name, then their favorite color, then their favorite food. Let's say this is in a processing loop and I want to set variables up for each value. For the first line, my values should look like this.
friendsName = "Bob";
favoriteColor = "blue";
favoriteFood = "pizza";
I read in the line and start out with
lineInFile = "Bob blue pizza";
strsplit seems like a good idea, but it outputs a cell array instead of a matrix of strings and I end up with
strsplit(lineInFile, " ") =
{
[1,1] = Bob
[1,2] = blue
[1,3] = pizza
}
I want something like
{friendsName,favoriteColor,favoriteFood} = strsplit(lineInFile, " ");
This gives me error: invalid lvalue function called in expression
Arrays can be used as lvalues, so I tried
cell2mat(strsplit(lineInFile, " "))
ans = Bobbluepizza
That's not what I want.
This worked.
[friendsName favoriteColor favoriteFood] = strsplit(lineInFile, " "){1,:}

How to write a expression for a linq to sql property?

My appologies upfront for the lengthy question. I made quite an effort to make my question as clear as possible in one go. Please bear with me. ;o) any help will be greatly appreciated!
I have the classes Branch and Text:
class Branch
int ID
Text WebDescription
and a bunch of other properties
class Text
int ID
string UK
string NL
string FR
string IT
and a bunch of other properties as well
I want to only display the ID of the branch and its description in the appropriate language. I want only one query (no extra round trips) which retrieves only two fields (not the whole object).
I found three solutions
Via the object model in the query
// good: no round trips
// good: clean sql
// bad: impossible to use the currentUserLanguage parameter
var lang = "NL";
var dbProject = new ProjectDataContext();
var query = from b in dbProject.GetTable<Branch>()
select new
{
b.ID,
WebDescription = b.WebDescriptionObject.NL // <-- problem
};
var text = query.First().WebDescription;
Via the object model after the query
// good: no round trips (eager loading of text object)
// good: possible to use the currentUserLanguage parameter
// bad: loads the *whole* branch and text object, not just two fields
var lang= "NL";
var dbProject = new ProjectDataContext();
var query = from b in dbProject.GetTable<Branch>()
select new
{
b.ID,
WebDescription = b.GetWebDescriptionAsString(lang)
};
var text = query.First().WebDescription;
Using an expression
// good: I have the feeling I am on the right track
// bad: This doesn't work :o( throws an exception
var lang= "NL";
var dbProject = new ProjectDataContext();
var query = from b in dbProject.GetTable<Branch>()
select new
{
b.ID,
WebDescription = b.GetWebDescriptionAsExpression(lang)
};
var text = query.First().WebDescription;
Here is code for the two methods GetWebDescriptionAsString and GetWebDescriptionAsExpression.
public string GetWebDescriptionAsString(string lang)
{
if (lang== "NL") return WebDescriptionObject.NL;
if (lang== "FR") return WebDescriptionObject.FR;
if (lang== "IT") return WebDescriptionObject.IT;
return WebDescriptionObject.UK;
}
public Expression<Func<Branch, string>> GetWebDescriptionAsExpression(string lang)
{
if (lang== "NL") return b => b.WebDescriptionObject.NL;
if (lang== "FR") return b => b.WebDescriptionObject.FR;
if (lang== "IT") return b => b.WebDescriptionObject.IT;
return b => b.WebDescriptionObject.UK;
}
Without really answering the question, the cleanest approach would be to change the Text structure into a more normalized form like:
Text
ID
TextTranslation
ID
TextID
Lang
TextValue
where each text has a number of translations, one for each language.
The query would become something like:
var q =
from branch in dbProject.Branches
join text in dbProject.Texts on branch.TextID = text.ID
join translation in dbProject.TextTranslations on text.ID = translation.TextID
where translation.Lang == lang
select new
{
branch.ID,
WebDescription = translation.TextValue
};
This approach has other advantages as well, for example adding a new language will not change the model structure.
This would be very easy to do if you used a stored procedure. Are you opposed to using SP's as a solution?
If a stored procedure works, then I am happy to use it.
Thank you for you prompt reply.
I made a quick attempt. The UDF was already there, I just didn't know how to use it. The performance dropped significantly. The first solution is 3 times faster. In my understanding, this approach would require extra round trips to the database. Is that correct?
var query = from b in dbProject.GetTable<Branch>()
select new
{
b.ID,
WebDescription = db.fGetText(b.WebDescriptionID, (currentUserLanguage))
};
Without understanding your whole problem
create a stored procedure like this:
CREATE PROCEDURE spGetTheTextINeed #Language char(2), #BranchID int
AS
/* I don't know how your database is structured so you need to write this */
SELECT MyText from MyTable WHERE Language=#Language and Branch=#BranchID
Then you need to add the sp to your DBML and then you can just call the sp you need with the appropriate parameters:
var query = myDataContext.spGetTheTextINeed("NL",[your branch number])
Dim str As String
str = query.MyText
The code above is not to be exact - I don't understand your full requirements but this should get you started.