Javascript get JSON into arrays, combine and use elsewhere - javascript

I'm currently a bit stuck trying to combine two arrays (one of dates, one of times).
I've written a PHP script to pass out JSON from an SQL table I have containing the data, but I'm struggling to turn the two arrays into a single datetime array in JavaScript.
The JSON is coming out as:
{
"dates": [
"2016-03-13",
"2016-03-13",
"2016-03-14",
"2016-03-14"
],
"times": [
"16:41:13",
"17:36:57",
"08:53:02",
"21:53:11"
]
}
So far I'm using this to collect the data, though I'm really not sure where to go from there (or if what I'm getting is even an array?):
$(document).ready(function() {
var API_URL = "php_script.php";
$.getJSON(API_URL, function(data) {
var dates = data.dates;
var times = data.times;
console.log(dates + " " + times);
});
});
The output of which is:
2016-03-13,2016-03-13,2016-03-14,2016-03-14,16:41:13,17:36:57,08:53:02,21:53:11
I'd prefer:
[2016-03-13 16:41:13,2016-03-13 17:36:57,2016-03-14 08:53:02,2016-03-14 21:53:11]
To be passed out as an array which I can then use with chart.js.
The dates and times will be used for the X axis and the time between them for the Y axis, so it would be useful to be able to complete some kind of datetime math on the data, if possible.

Here's a way to manually mix them together.... The gist is to manually splice the strings together and then use Date.parse() to make the date objects.
var dates = [
"2016-03-13",
"2016-03-13",
"2016-03-14",
"2016-03-14",
];
var times = [
"16:41:13",
"17:36:57",
"08:53:02",
"21:53:11",
];
var both = [];
for (var i = 0; i < dates.length; i++) {
both.push(new Date(Date.parse(dates[i] + " " + times[i])));
}
console.log("%j",both);

This sort of thing is easy if you use a library like lodash. In this case you would want _.zip
var dates = data.dates;
var times = data.times;
var zipped = _.zip(dates, times);
var text = _.reduce(zipped, function(aggregate, item) { return ',' + item[0] + ' ' + item[1]; });
console.log(text);

try splitting the dates and times with , and concat each of them by using loop
var data = {
"dates": [
"2016-03-13",
"2016-03-13",
"2016-03-14",
"2016-03-14"
],
"times": [
"16:41:13",
"17:36:57",
"08:53:02",
"21:53:11"
]
}
var datetimes = [];
for (var i = 0; i < data.dates.length; i++) {
datetimes.push(data.dates[i] + ' ' + data.times[i]);
}
document.write('<pre>' + JSON.stringify(datetimes, 0, 4) + '</pre>')

Related

Calculation with Array values not working in JS

in my current project I need a Pie Chart in which calculated values should be displayed.
I have now five values as array, which I need to add, so that I have the desired value.
But now I am a bit confused, because no matter if I convert the arrays to sting, or use them directly in the addition, they are always lined up and not added.
What am I missing here?
In a subtraction directly after the calculation works, but here I still have a date value (number of days in the month) in the calculation.
Why does this calculation work?
My Problem
For example I get here "02400" as result and not "6".
var training = training_intervall + training_longrun + training_speedwork + training_stabilisation + training_competition;
My JS function:
function userDiaryMonthTrainingStats(user_id) {
$.ajax({
url: "../diary/includes/training/diary-training-monthly-training-stats.php?user_id=" + user_id,
type: "GET",
success: function(monthly_training_stats) {
var training_intervall = [];
var training_longrun = [];
var training_speedwork = [];
var training_stabilisation = [];
var training_competition = [];
var training_injury = [];
for(var i in monthly_training_stats) {
training_intervall.push(monthly_training_stats[i].training_intervall),
training_longrun.push(monthly_training_stats[i].training_longrun),
training_speedwork.push(monthly_training_stats[i].training_speedwork),
training_stabilisation.push(monthly_training_stats[i].training_stabilisation),
training_competition.push(monthly_training_stats[i].training_competition),
training_injury.push(monthly_training_stats[i].training_injury)
}
var date = new Date();
var month = date.getMonth() + 1;
var year = date.getFullYear();
daysInMonth = new Date(year, month, 0).getDate();
training_intervall = training_intervall.toString();
training_longrun = training_longrun.toString();
training_speedwork = training_speedwork.toString();
training_stabilisation = training_stabilisation.toString();
training_competition = training_competition.toString();
var training = training_intervall + training_longrun + training_speedwork + training_stabilisation + training_competition;
var training_free = daysInMonth - training_intervall - training_longrun - training_speedwork - training_stabilisation - training_competition - training_injury;
var userMonthlyTrainingStatsData = {
datasets: [{
data: [training, training_injury, training_free],
backgroundColor: ['#36a2eb', '#e33b3b', '#4bc07d']
}],
labels: [
'Training',
'Injury',
'Free'
]
};
........
}
})
}
use parseInt() to change from a string to int then you can add the strings as they are now numbers
var training = parseInt(training_intervall) + parseInt(training_longrun) + parseInt(training_speedwork + parseInt(training_stabilisation) + parseInt(training_competition);
if you want the result back to a string simply put after this
training=""+training
Two problems in your code:
training_intervall and the other 4 variables you want to add are arrays, you should iterate them.
The values are strings, using + with strings results in a new concatenated string. To convert easily a string number to a number (example "1" to 1), you can:
const myString = "1"
const myNumber = myString * 1 // myNumber = 1

How to most efficiently generate string from array of objects in javascript?

I have the following:
var students = [{name:"Jordan", age:"6"},{name:"Jake", age:"7"},{name:"Mark", age:"10"}]
I want to generate a string like this:
"Jordan,6|Jake,7|Mark,10"
What is the most efficient way to do this?
I am currently using:
var studentstr = "";
for(var i = 0; i < students.length; i++) {
studentstr = students['name'] + "," + students['age'] + "|"
}
studentstr = studentstr.substring(0, studentstr.length - 1);
Also, performance-wise, if I had an array of 2,000 items, is it "costly" to perform this transformation? The resulting string contains both keys in the object and not a single join on one object in the property.
You can map each student object to a string and then join them all with |:
var studentstr = students.map(function (student) {
return student.name + ',' + student.age;
}).join('|');
Also, performance-wise, if I had an array of 2,000 items, is it "costly" to perform this transformation?
No.
Yes, using string concatenation in a loop is costly. The string grows for each iteration, and each time you have to copy the entire previous string to create the new version. The execution time of the loop grows exponentially to the number of items.
You can put the string for each object in an array, then join them together:
var students = [{name:"Jordan", age:"6"},{name:"Jake", age:"7"},{name:"Mark", age:"10"}];
var items = [];
for (var i = 0; i < students.length; i++) {
items.push(students[i].name + ',' +students[i].age);
}
var str = items.join('|');
// display result in snippet
document.write(str);
map works well for this:
var students = [{name:"Jordan", age:"6"},{name:"Jake", age:"7"},{name:"Mark", age:"10"}];
var result = students.map(function(student) {
return student.name + ',' + student.age;
});
alert(result.join('|'));
Try this and see your console:
var string = '';
for (var s in students) {
string += students[s].name + ', ' + students[s].age + ' | ';
}
console.log(string);
Fiddle: http://jsfiddle.net/80ss0u14/
I do not think it is costly to go on with such approach. It may be the most efficient way to iterate through the data.

How can I group data returned in JSON format and return it?

I have a JSON string of the form:
[
{"ID":153,"CircuitID":53,"StartTime":"2014-11-12 12:45:00","EventFormatID":224,"TotalPlaces":8,"BookedPlaces":0,"ProvisionalPlaces":0},
{"ID":161,"CircuitID":53,"StartTime":"2014-11-12 17:15:00","EventFormatID":224,"TotalPlaces":0,"BookedPlaces":0,"ProvisionalPlaces":0},
{"ID":734,"CircuitID":53,"StartTime":"2014-11-12 18:30:00","EventFormatID":231,"TotalPlaces":14,"BookedPlaces":0,"ProvisionalPlaces":0}
]
In place of Event Format ID and Circuit ID I will be returning the names
What I need to do is group the results by Event Format ID and return the results in the following format:
Event 224 : 12:45 (8 places available), 17:15 (0 places available)
Event 231 : 18:30 (14 places available)
I can't seem to figure out how to loop through the data, group it by Event Format ID to present it in the required format!
Thanks
Can you use any additional libraries? I'd use lo-dash which would make this relatively simple:
var grouped = _.groupBy(data, "EventFormatID");
_(grouped).forEach(function (group, key) {
console.log("Event:" + key);
_(group).forEach(function (course) {
console.log(course.StartTime + " (" + course.TotalPlaces + " places available)");
});
});
Obviously the example above logs to the console but it'd be fairly simple to change to build up whatever string or object you need.
This is easier with lodash/underscore, or even with ES5 array and object methods, but since you asked about pure JS:
var data = {}, results = [], i, j, id, time, obj, evts; // obj is your object above
for (i=0; i<obj.length; i++) {
id = obj[i].EventFormatID;
time = obj[i].StartTime; // you can simplify to get just the time, not the datetime, if you prefer
data[id] = data[id] || [];
data[id].push({"time":time,"places":obj[i].TotalPlaces});
}
// now you have a proper data structure, just print it out
for (i in data) {
if (data.hasOwnProperty(i)) {
// just show the output properly formatted
evts = [];
for (j=0;i<data[i].length;j++) {
evts.push(data[i][j].time+" ("+data[i][j].places+" places available)");
}
results.push("Event "+i+" : "+evts.join(","));
}
}
ES5 makes this so much easier
var data = {}, results = [], obj; // obj is your object above
obj.forEach(function(val,i) {
data[val.EventFormatID] = data[val.EventFormatID] || [];
data[val.EventFormatID].push({"time":val.StartTime,"places":val.TotalPlaces});
});
// now you have a proper data structure, just print it out
Object.keys(data).forEach(function(key) {
var value = data[key], evts = [];
value.forEach(function(elm) {
evts.push(elm.time+" ("+elm.places+" places available)");
});
results.push("Event "+key+" : "+evts.join(","));
});
And lodash is even easier.
Please take a look that:
http://jsfiddle.net/m260n5ud/
html
<div id="contentDiv"></div>
js
function tidyUp(jsonArray) {
var myObject = {};
for (i = 0; i < jsonArray.length; i++) {
var key = jsonArray[i]['EventFormatID'];
var time = jsonArray[i]['StartTime'].replace(' ', ':').split(/[- :]/);
time = time[3] + ":" + time[4];
var totalPlace = jsonArray[i]['TotalPlaces'];
if (myObject[key] == null) {
myObject[key] = "Event : " + key + " : " + time + " ( " + totalPlace + " places available)";
} else {
myObject[key] += ", " + time + " ( " + totalPlace + " places available)";
}
}
console.log(myObject);
for (var k in myObject) {
document.getElementById('contentDiv').innerHTML += myObject[k] + "<br/>";
}
}

extract and format value in JSON string

I just started working with JSON strings. i have an array of json strings that contains json strings like
{"ID":"3", "LinkFilename":"Test.txt", "Sender":"abc#hotmail.com", "Created":"2014-07-07T20:13:18.000Z"}
what i want to do is to take change the value of "Created" key (which is a date) and omit its time part so it must show only date part. i want to produce something like:
{"ID":"3", "LinkFilename":"Test.txt", "Sender":"abc#hotmail.com", "Created":"2014-07-07"}
The code to produce Json is as follows:
var ItemsEntries = [];
var listItemInfo = '';
var itemsCount = this.collListItem.get_count();
for (i = 0; i < itemsCount; i++) {
var item = this.collListItem.itemAt(i);
var ItemEntry = JSON.stringify(item.get_fieldValues());
ItemsEntries.push(ItemEntry);
listItemInfo += ItemsEntries[i].toString(); + '\n';
}
Please guide me through this.
If you have the Javascript object:
var item = {
"ID":"3",
"LinkFilename":"Test.txt",
"Sender":"abc#hotmail.com",
"Created":"2014-07-07T20:13:18.000Z"
}
and you want to change the Created field in the way you described, you can first create a new Date object out of the Created field value and just extracting the pieces you care about with the functions included in the Date API (http://www.w3schools.com/jsref/jsref_obj_date.asp).
This code should be able to change obj to the format you require:
var formatItem = function(item){
var date = new Date(item["Created"]);
var formattedDate = date.getFullYear()
+ '-'
+ date.getMonth() + 1 // zero-based index...
+ '-'
+ date.getDate();
item["Created"] = formattedDate;
};
One caveat is that the month won't be padded on the left by a 0 if it's a single digit, but that's easy enough to fix on a case-by-case basis.

jQuery recursive wildcard selector from array and array push dynamically

Link to jsFiddle
I have many elements containing text in which I am using parseInt() to grab the values from a specific number of elements (based on the current month) and a specific selector wildcard and push those values into one of six arrays for use elsewhere. I am trying to clean up the code and make a compact loop to complete all of this.
I am able to get everything to work if I use six separate for loops, but I thought I might try to see if it is able to be done in one single loop.
So in the for loop below, I am trying to make the jQuery wildcard selector for the element ID be the current value of i (from statusArray) by trying something like $('[id*=statusArray[i]]) but that doesn't seem to be working.
Then I would like to push the data into the predefined appropriate array by something like statusArray[i]Array.push(...) but that doesn't work either. I've tried concatenating various ways but can't seem to get it to work.
Any help would be appreciated! Thank you in advance!
HTML:
<div id="jan_connected"></div> <!-- left empty to test for NaN -->
<div id="jan_busy">100</div>
<div id="jan_noanswer">100</div>
<div id="jan_abandoned">100</div>
<div id="feb_minutes">100</div>
<div id="feb_totals_calls_c">100</div>
<div id="feb_connected">100</div>
<div id="feb_busy">100</div>
<div id="feb_noanswer">100</div>
<div id="feb_abandoned">100</div>
Javascript:
var connectedArray = [];
var busyArray = [];
var noanswerArray = [];
var abandonedArray = [];
var minutesArray = [];
var callsArray = [];
// var date = new Date();
// var dateNumber = 1 + date.getMonth();
var dateNumber = 2;
var statusArray = ['minutes', 'total_calls', 'connected', 'busy', 'noanswer', 'abandoned']
for (i=0; i<dateNumber; i++) {
// Below I would like the id* to equal the current value of the statusArray iteration
if (isNaN(parseInt($('[id*=statusArray[i]]').slice(i).html()))) {
statusArray[i]Array.push("0"); // Trying to push into the appropriate array dynamically
} else {
statusArray[i]Array.push(parseInt($('[id*=statusArray[i]]').slice(i).html()));
}
}
You have syntax errors in couple of places..
this line
$('[id*=statusArray[i]]')
supposed to be
$('[id*=' + statusArray[i] + ']')
And
statusArray[i] Array.push("0");
should be
statusArray[i].push("0");
Push method is available on a Array , but statusArray[i] is not an array but a string.
Looks like you are looking for something like this
var connectedArray = [];
busyArray = [];
noanswerArray = [];
abandonedArray = [];
minutesArray = [];
callsArray = [];
dateNumber = 2;
statusArray = ['minutes', 'total_calls', 'connected', 'busy', 'noanswer', 'abandoned'];
var obj = {
'minutes': minutesArray,
'totals_calls': callsArray,
'connected': connectedArray,
'busy': busyArray,
'noanswer': noanswerArray,
'abandoned': abandonedArray
};
for (i = 0; i < statusArray.length; i++) {
$('[id*="' + statusArray[i] + '"]').each(function () {
var val = $(this).html();
if (isNaN(parseInt(val))) {
obj[statusArray[i]].push("0");
} else {
obj[statusArray[i]].push(val);
}
});
}
console.log('Minutes Array: ' + obj['minutes']);
console.log('Total Calls Array: ' + obj['totals_calls']);
console.log('Connected Array: ' + obj['connected']);
console.log('No Answer Array: ' + obj['noanswer']);
console.log('Abandoned Array: ' + obj['abandoned']);
console.log('Busy Array: ' + obj['busy']);
Check Fiddle

Categories

Resources