Filtering data in an array - javascript

I have an array that has 30 date objects. The date objects are indexed in the array from the minimum date value to the maximum date value. What I would like to do is retrieve only 7 dates from the array. Out of the 7, the first one should be the minDate and the last should be the maxDate, with 5 dates in the middle. The 7 numbers should increment evenly from the minDate to the maxDate. How would I accomplish this? Hope I was clear.
Thanks,
Tonih

well if you were trying to evenly distribute by date then make sure all your objects are in the date class then do array[29].getTime()-array[0].getTime() /7 for your average step, then do something like array.forEach() with a comparason function to try and get the closest to each step.
--edit--
try something like:
//dateArray is array of dates
var targetTime:Number;
var filteredarray:Array = new Array();
var step = dateArray[29].getTime()-dateArray[0].getTime() /7
var smallestdist:Number;
var currentIndex:int;
filteredarray.push(dateArray[0]); //Add the first entry
targetTime = dateArray[29].getTime(); //set the lowest point
for(var i=1; i<7; i++){ //loop 6 more times
smallestdist = Number.POSITIVE_INFINITY; //set a large smalldist
currentIndex = 0; //Set a small index
targetTime += step; //increment the target time
dateArray.forEach(testDate); //loop through the array and test with testDate function
filteredarray[i] = dateArray[currentIndex] //Add the result to the dateArray
}
function testDate(item:Date, index:int, array:Array){
//Check the absolute value against current stored distance
if(Math.abs(item.getTime() - targetTime) < smallestdist){
//if less then set this as new target
smallestdist = Math.abs(item.getTime() - targetTime);
currentIndex = index;
}
}
of course this is dealing with a preumed even spread of dates, there could be the posibility of adding the same date to several different points if all of dateArray are clumped together, could be optimised, but see what you can do with it.
i havnt tested this code, but it should work pretty out of the box. have a look at these if you have a problem:
Array::forEach()
Date::getTime()

Related

Using Jscript Add ONLY the integers in a 2D array. Then working out the difference between each month of the same array to get the average difference

Javavscript help (array at bottom)
I have a 2D array which holds a date of month in one column (a string) and an integer next to it i.e. array= ['Oct 2020' , 23456], ['Nov 2020' , 34567], ['Dec 2020' , -4567]...etc I have to work out:
total amount of months in this array (which I've managed),
the total of all the profit/loss form the integers (which I've managed alt methods welcome it'll help me learn more),
the average difference of profit/loss between each month's by calculating the difference between each month first then adding and dividing by total number of months,
the month with the biggest profit in the array
the month with biggest lost in the array.
I'm able to provide the code. I think I understand how to do this in a 1D array but with a 2D array the results didn't work. Please could I have some help and a walk through of your answer. I don't mind how its worked out but if you could have an example with the reduce function in your answer and an answer without that would be great if not no problem.
var finances = [
['Jan-2010', 867884],
['Feb-2010', 984655],
['Mar-2010', 322013],
['Apr-2010', -69417],
['May-2010', 310503],
['Jun-2010', 522857],
['Jul-2010', 1033096],
['Aug-2010', 604885],
['Sep-2010', -216386],
['Oct-2010', 477532],
['Nov-2010', 893810],
['Dec-2010', -80353],
['Jan-2011', 779806],
['Feb-2011', -335203],
['Mar-2011', 697845],
['Apr-2011', 793163],
['May-2011', 485070],
['Jun-2011', 584122],
['Jul-2011', 62729],
['Aug-2011', 668179],
['Sep-2011', 899906],
['Oct-2011', 834719],
['Nov-2011', 132003],
['Dec-2011', 309978],
['Jan-2012', -755566],
['Feb-2012', 1170593],
['Mar-2012', 252788],
['Apr-2012', 1151518],
['May-2012', 817256],
['Jun-2012', 570757],
['Jul-2012', 506702],
['Aug-2012', -1022534],
['Sep-2012', 475062],
['Oct-2012', 779976],
['Nov-2012', 144175],
['Dec-2012', 542494],
['Jan-2013', 359333],
['Feb-2013', 321469],
['Mar-2013', 67780],
['Apr-2013', 471435],
['May-2013', 565603],
['Jun-2013', 872480],
['Jul-2013', 789480],
['Aug-2013', 999942],
['Sep-2013', -1196225],
['Oct-2013', 268997],
['Nov-2013', -687986],
['Dec-2013', 1150461],
['Jan-2014', 682458],
['Feb-2014', 617856],
['Mar-2014', 824098],
['Apr-2014', 581943],
['May-2014', 132864],
['Jun-2014', 448062],
['Jul-2014', 689161],
['Aug-2014', 800701],
['Sep-2014', 1166643],
['Oct-2014', 947333],
['Nov-2014', 578668],
['Dec-2014', 988505],
['Jan-2015', 1139715],
['Feb-2015', 1029471],
['Mar-2015', 687533],
['Apr-2015', -524626],
['May-2015', 158620],
['Jun-2015', 87795],
['Jul-2015', 423389],
['Aug-2015', 840723],
['Sep-2015', 568529],
['Oct-2015', 332067],
['Nov-2015', 989499],
['Dec-2015', 778237],
['Jan-2016', 650000],
['Feb-2016', -1100387],
['Mar-2016', -174946],
['Apr-2016', 757143],
['May-2016', 445709],
['Jun-2016', 712961],
['Jul-2016', -1163797],
['Aug-2016', 569899],
['Sep-2016', 768450],
['Oct-2016', 102685],
['Nov-2016', 795914],
['Dec-2016', 60988],
['Jan-2017', 138230],
['Feb-2017', 671099]
];
code for how many months:
let monthsTotal = finances.length;
console.log("Total months: ", monthsTotal);
my first attempt to try and find the total profits/losses (i.e. sum of all integers). It just printed out the array in a messy form
const netTotal =finances.reduce((sum, curVal) => sum + curVal);
console.log("Total Profits/Loses: ", netTotal);
my second attempt actually works to find the sum which i have called netTotal
let netTotal = finances.map(function(v) { return v[1] }) // second value of each
.reduce(function(a,b) { return a + b }); // sum
console.log('Total:', netTotal)
so just the the last 3 bullet points technically
In the netTotal calculation, we don't need the extra trip through the array to get the integer value. Just pull it out with [1] as you go:
let netTotal = finances.reduce((a,b) => a + b[1]);
Getting the differences between months is simple if you handle the special case of the first month not having a prior month to compare to.
let diffs = finances.map((el, index) => {
// on the first one, assume the prior value is 0
let priorValue = index === 0 ? 0 : finances[index-1][1]; // edit
return el[1] - priorValue;
})
let totalDiffs = diffs.reduce((a,b) => a + b); // simple sum
let averageDiffs = totalDiffs / finances.length
Max and min are a little extra work because the calculation should track the months also. Here's a way to do it where the max/min thing being tracked is the nested array itself.
let maxArr = ['', -Number.MAX_VALUE] // everything is bigger than this
let minArr = ['', Number.MAX_VALUE] // everything is smaller than this
for (let i=0; i<finances.length; i++) {
let arr = finances[i];
if (arr[1] > maxArr[1]) maxArr = arr;
if (arr[1] < minArr[1]) minArr = arr;
}

Datetime array to array with dates, get corresponding time afterwards

Specific situation.. I'm having an array filled with datetimes I pull in via an api.
Users should be able to select a date from a datepicker (only showing dates available in the array) and afterwards see the corresponding time.
So what I've done..
The original array is obtained via php, so before starting to populate the datepicker with possible dates I create an extra array with dates only.
Since I maintain the key's it's possible to put these 2 arrays next to eachother.
Array looks as following:
["8-8-2017,07:00", "26-8-2017,07:00"];
So far so good...
After a user picks a date I trigger this to be able to start digging for the time corresponding that date.
Now it's getting messy...
$('#datepick').datepicker().on("input change", function(e) {
$("#uur").text('');
var selecteddate = e.target.value;
var searchArr = datesArray;
var ind = searchArr.indexOf(selecteddate.toString());
var result = datesArray.filter(function(item) {
return typeof item == 'string' && item.indexOf(selecteddate.toString()) > -1;
});
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
var final = afterComma.replace(":", "u");
$("#uur").text("De warming up party gaat van start rond " + final);
});
The result is that this only works on the last element of the array.
Because I'm splitting based on the comma's. Now I know the easiest way to work arround this would be to change the , that's seperating date and time in another symbol but still I'm wondering why this couldn't be easier.
You convert whole array to string every time. You should change following code:
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
To this;
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
Edit:
I also missed the loop above
//for every item in result, afterComma will refer to related minute string
for (var item in result) {
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
// Do rest here
}

count how many data in array and increment javascript

I'm new in stackoverflow:
Here is my issue, i would like to count how many tickets by month a user has and push it in my array,
i did that:
for(j=0; j< data.data.tickets.length ;j++){
var requesterid = data.data.tickets[j].requester_id;
var created_at = data.data.tickets[j].created_at;
var today = new Date().toISOString().slice(0, 7);
if(created_at.includes(today)&& requesterid == cleartab[requesterid]['id']){total ++}
var arrayRef2 = cleartab[requesterid]['monthly'] || [];
cleartab[requesterid]['monthly'] = arrayRef2.concat([{"janvier":total}], [{"fevier":"fef"}]);
}
The problem is that it gave me wrong result.
Here is my array:
My array
If my question is not clear, i can re-explain or tell me if you need something more to answer it
I hope you can help me
My issue:
Some people should not have ticket the result is not the good one. I would like to be sure that it increment only one people when 1 ticket has been sent in the current month. For now, when someone send a ticket in the current month, every user got +1 ticket in the current month. But what i want is that: it increment only for one user, the user who sent the ticket. Is that clear ?
Based on my understanding of the problem, you could try as below:
for(j=0; j< data.data.tickets.length ;j++){
var requesterid = data.data.tickets[j].requester_id;
var created_at = data.data.tickets[j].created_at;
var today = new Date().toISOString().slice(0, 7);
// read the monthly for a given requestor or
// initialize the new array by setting the total
// to 0 "janvier:0
var arrayRef2 = cleartab[requesterid]['monthly'] ||
[{"janvier":0}, {"fevier":"fef"}];
if(created_at.includes(today) &&
requesterid == cleartab[requesterid]['id']){
// increment the total, very first time the value of
// arrayRef2[0].janvier will be zero, but in
// next iteration it will be always the previous value
arrayRef2[0].janvier++;
}
cleartab[requesterid]['monthly'] = arrayRef2;
}

Looping thought a javascript / JQuery array and getting a 'grand' total

Ok, I have been working on this for some time, I have some close to getting it to work but not completely. So what I am doing is adding the value from a weekly input form into an array with its key.
There will be no limit on the number of rows as I can (and this works fine) AJAX add a row to the form with a button.
I currently add all the totals for each day together, this works, as all the Mondays have a .Monday class on them (I can post that code it need, please just ask) and each other day.
I have also got an id on each input which as the day of the week and a count, so #Monday0, #Monday1, same for each day and each row ect.
Now what I am doing with the code below, is to add the week up and then display that (console log for now) in that weeks row. So I want to add all the daily ids, Monday though to Sunday that end in 0, then do the same for 1 and so on.
var LoadHourTotals = function() {
$('.TimebreakdownInput').change(function() {
var InputArrays = []; //Array to store all weekly inputs
var Totals = []; //Store Array total for display
GetCurrentID = $(this).attr('id');
CurrentCount = GetCurrentID.charAt(GetCurrentID.length-1)
var WeeklyArray = ["Monday"+CurrentCount,"Tuesday"+CurrentCount,"Wednesday"+CurrentCount,"Thursday"+CurrentCount,"Friday"+CurrentCount,"Saturday"+CurrentCount,"Sunday"+CurrentCount];
$.each(WeeklyArray, function(k, v) {
var values = parseFloat( $('#'+v).val() );
if (isNaN(values)) { values = 0; } //Set value to 0 if its not a number
if (!values) { values = 0; }
InputArrays.push({ key: CurrentCount, hours:values });
});
console.log(InputArrays);
//$('.TimebreakdownTotalHours').html(Totals); //Display / Add total into HTML
});
} //End of LoadHourTotals function
I think I am close with this, each daily input is saved into its own array with a key count and its value for that day. For example, 0:XX 0:XX (this seven times, all for the 1st row). This is then repeated for each row as needed.
If what I have done is not right or there is a better method for doing this, then please let me know.
But now what I need to do is go though each key, take its value, getting a 'grand' total for all seven inputs, then display or save that total into a new array (which is what I was trying to do) then display / console log each weekly total.
I have gone though a number of posts on here but I could not find anything that fits for my problem.
All help very welcome.
If I have not posted some code that is need then please let me know.
Please let me know if I have not explained myself right.
Many Thanks.
Its ok, I have found an answer. I tried this but it did not work,
var total = 0;
$.each(InputArrays,function() {
total += this;
console.log(total);
});
But some playing around with the code, I console loged 'this' and tried the following which now seems to work. Thanks
var total = 0;
$.each(InputArrays,function() {
total += this.hours;
console.log(total);
});

How do I loop through objects and categorize by timestamps in Javascript?

I have an array of objects that have a keys called timestamp and motion. motion contains a value and timestamp contains a unix timestamp. I want to iterate over a number of the objects and find what "time of day" period they correspond to, I then want to total up the motion values for that given time of day and save the entire thing in an array of arrays. I want the duration to be changeable.
Let's say these are my objects;
{
timestamp: 1397160634,
motion: 2,
id: '534771d8c311731e21c75c9f'
},
{
timestamp: 1397160634,
motion: 3,
id: '534771d8c311731e21c75c9f'
}
Now I create my results array
var sampleDuration = 60; // Min
var minutesInDay = 1440;
var samplesPerDay = minutesInDay/sampleDuration;
var finalResultItem = []
for (var i = 0; i < samplesPerDay; i++) {
var IndividualresultArray = []
IndividualresultArray.push(60*i);
IndividualresultArray.push(0);
finalResultItem.push(IndividualresultArray);
}
I now have an array of arrays with each subarray's first item being a number (corresponding to a minute stamp) and the second value being zero.
I would now like to loop through all my objects and increment the second value (motion) based on the time of day range that is in the timestamp
_forEach(objects, function (object) {
{
// grab the timestamp
// figure out which minute range it coresponds to
// increment the array value that corresponds to the minute stamp
// rinse and repeat
}
this is where I go blank, I need the end result to look something like this
[[30, 5],[60, 20],[90, 5],[120, 0] .........]
or it could even look like this
[[000002400, 5],[000003000, 20],[000003600, 5],[000004200, 0] .........]
where the first value is a timestamp that ignores the year, month, and day, and only considers the time of day.
I have considered using moment.js in some capacity but I'm not sure how. Any help with this problem would be great.
I created a jsFiddle for you. The motion increment logic should look like (I'm using jQuery here but you get the point)
// Loop through and increment motion
$.each(objs, function (idx, obj) {
var date = new Date(obj.timestamp * 1000); // Convert to milliseconds
var minutesInDay = date.getUTCHours() * 60 + date.getUTCMinutes(); // Remove UTC for local time!
var minuteRange = Math.floor(minutesInDay / sampleDuration);
finalResultItem[minuteRange][1] += obj.motion;
});
EDIT: Removed some discussion after your edit. I also used more generic logic based on sampleDuration.
This should do it:
_forEach(objects, function (object) {
var date = new Date(objec.timestamp*1000);
var minuteOfDay = date.getUTCHours()*60+date.getUTCMinutes();
finalResultItem[minuteOfDay][1] += object.motion;
})
For a variable sample rate, employ a secondOfDay and divide that by your sampleDuration, then floor it to get your array index.

Categories