get previous years in array using momentjs - javascript

How can I generate a list of array till today? I can't hardcode [2016,2017,2018], because I have to do it every year.
function (numberOfYearsBack) { // }

Get the current year using getFullYear(), and use Array.from() with a map function to declare and initialize an array with the values you need:
const years = (back) => {
const year = new Date().getFullYear();
return Array.from({length: back}, (v, i) => year - back + i + 1);
}
console.log(years(3));

function years(count, startYear){
const yearList = [];
const year = startYear || new Date().getFullYear();
for(let i = 0; i < count; i+=1 ){
yearList.push(Number(year)-i)
}
return yearList.sort((a,b)=>a-b)
}
console.log(years(10, 2022))

Related

Loop through an array and push it into array of object javascript

So i try to loop an Array and push it into object within this code:
const past7Days = [...Array(7).keys()].map(index => {
var date = new Date();
const local = new Date();
local.setMinutes(date.getMinutes() - date.getTimezoneOffset());
local.setDate(date.getDate() - index);
return local.toJSON().slice(0, 10);
});
let data={};
let arr=[]
for (var i = 0; i < past7Days.length; i++) {
console.log(past7Days[i]);
return arr.push(data["key"] = past7Days[i])
}
what i expected is :
[{key:"date"},{key:"date2"}]
can somebody tellme where did i do wrong here
In your attempt there is only one such object created (data) and the assignments to data[key] just keep overwriting the same object's property. Moreover, that push will not push an object, but the string that is assigned.
You can create each object immediately in your first iteration, with a { key: string-value } object literal and returning that.
Unrelated, but you should not use getTimezoneOffset like that. In boundary cases (like when daylight saving switches on the same day) it can have undesired results. Instead consider that you can convert a date to a string with respect of the current locale's timezone. For instance, the Swedisch locale also uses "YYYY-MM-DD" format (like toJSON), and when used with toLocaleDateString it will use the locale's date:
const past7Days = Array.from({length: 7}, (_, index) => {
const local = new Date();
local.setDate(local.getDate() - index);
return { key: local.toLocaleDateString('en-SE') };
});
console.log(past7Days);
Assuming you want exactly one array where the elements are like {"key": <string representation of a date> }, you can try this:
const past7Days = [...Array(7).keys()].map(index => {
var date = new Date();
const local = new Date();
local.setMinutes(date.getMinutes() - date.getTimezoneOffset());
local.setDate(date.getDate() - index);
return local.toJSON().slice(0, 10);
});
let arr=[]
for (var i = 0; i < past7Days.length; i++) {
// console.log(past7Days[i]);
arr.push( {key: past7Days[i] } )
}
console.log(arr);

How to extract the month values from the res.body.results array of objects using JS Array map()

Also trying to get that custom code that extracts the months from the string with regex in my code snippet. I believe I am close but not quite. Console log is returning "undefined" values for the key/value pairs and 0 for the months when it should return 60. Any thoughts on how to restructure this would be very much appreciated! I am trying to get the highest number of months/years from an array and set it to a property in HubSpot. Thank you kindly for any advice on how to properly configure to get correct values.
hubspotClient.crm.lineItems.batchApi.read({
inputs,
properties: ['hs_recurring_billing_period', 'recurringbillingfrequency',]
})
.then(res => {
const inputs = res.body.results.map(result => {
result.properties.recurringbillingfrequency =
result.properties.recurringbillingfrequency;
result.properties.months = Number(result.properties.months);
return { term: hs_recurring_billing_period, frequency: recurringbillingfrequency };
})
console.log(inputs);
let term = 0;
const largestNum = (years) => {
//let term = 0;
for (let i=0; i <res.body.results.length; i++){
let { recurringbillingfrequency, hs_recurring_billing_period } =
res.body.results[i].properties;
console.log(recurringbillingfrequency, hs_recurring_billing_period)
if(recurringbillingfrequency = "Annually")
{
let months = Number(hs_recurring_billing_period.replace(/\D/g, ''));
let years = months / 12;
// let term = 0;
if (years[i] > term) {
term = years[i];
}
}
}
return term;
}
console.log(largestNum(term));
return;
The map function looks strange to me:
const inputs = res.body.results.map(result => {
result.properties.recurringbillingfrequency = result.properties.recurringbillingfrequency;
result.properties.months = Number(result.properties.months);
return { term: hs_recurring_billing_period, frequency: recurringbillingfrequency };
})
within the scope of the mapping function, recurringbillingfrequency and hs_recurring_billing_period in the return object are not defined. Would it work by replacing the return value with as so?
return {
hs_recurring_billing_period: result.properties.hs_recurring_billing_period,
recurringbillingfrequency: result.properties.recurringbillingfrequency
};
Also, I am not quite sure how this line is necessary:
result.properties.recurringbillingfrequency = result.properties.recurringbillingfrequency;
So either this loop will work and extract the months and set to years or you can use Lodash with one line of code.
let term = 0;
for (let i=0; i <inputs.length; i++){
let { recurringbillingfrequency, hs_recurring_billing_period } =
inputs[i];
console.log(recurringbillingfrequency, hs_recurring_billing_period)
if(recurringbillingfrequency.toLowerCase() === 'annually')
{
let months = hs_recurring_billing_period;
let years = months / 12.0;
/*
let highest = 0;
function getHighestTerm(values) {
for (let j=0; j < values.length; j++)
if (j === 0) {
highest = values;
} else if (highest > values[j]) {
highest = values[j];
}
return highest;
}
*/
term = _.max(_.map(inputs, 'hs_recurring_billing_period')) / 12.0;

How to group array of dates by month and year

Hi I'm having an array of the date object
"["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z",
"2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z",
"2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z",
"2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z",
"2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z",
"2020-12-16T06:30:00.000Z"]"
I need to format into this
[
{
"month": "12",
"year": "2020",
"dates": [1,14,25]
},
{
"month": "10",
"year": "2020",
"dates": [1]
}
]
How to format like this help me. I have done like this but not completed I was stuck in adding dates. I know this is not the correct way of doing it. Please don't bother the code I have written I know it's garbage.
dateArray.reduce((initial,next)=>{
let result=[]
if(isSameYear(new Date(initial),new Date(next) &&
isSameMonth(new Date(initial),new Date(next))){
result.push({
month:new Date(nex).getMonth(),
year: new Date(next).getFullYear
})
}
})
You can group dates based on year and month in an object accumulator.
const data = ["2021-01-05T06:30:00.000Z", "2021-01-06T06:30:00.000Z", "2021-01-20T06:30:00.000Z", "2021-02-09T06:30:00.000Z", "2021-02-23T06:30:00.000Z", "2021-02-16T06:30:00.000Z", "2020-12-08T06:30:00.000Z", "2020-12-15T06:30:00.000Z", "2020-12-02T06:30:00.000Z", "2020-12-09T06:30:00.000Z", "2020-12-16T06:30:00.000Z" ],
result = Object.values(data.reduce((r, date) => {
const [year, month, day] = date.substr(0,10).split('-');
const key = `${year}_${month}`;
r[key] = r[key] || {month, year, dates: []};
r[key].dates.push(day);
return r;
},{}));
console.log(result);
When you group things in general, it's easier to group them into an object. The reason is you don't have to search an array for a matching result to append to, you only have to look up a key to concatenate to.
Here's one solution that builds an object, grouped by string keys built out of the month and year, and then maps over the values of that object to build the array you're looking for, by splitting the string keys into their significant parts.
const dates = ["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z","2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z","2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z","2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z","2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z","2020-12-16T06:30:00.000Z"];
const grouped = dates.reduce((accumulator, date) => {
const parsed = new Date(date);
const year = parsed.getFullYear();
const month = parsed.getMonth();
const groupKey = `${month},${year}`;
accumulator[groupKey] = accumulator[groupKey] || {dates: []};
accumulator[groupKey].dates.push(parsed.getDay());
return accumulator;
}, {});
const result = Object.entries(grouped).map(([key, dates]) => {
const parts = key.split(',');
return {
month: parts[0],
year: parts[1],
dates: dates
};
});
console.log(result);
maybe do it in two passes
const dateArray = ["2021-01-05T06:30:00.000Z", "2021-01-06T06:30:00.000Z", "2021-01-20T06:30:00.000Z", "2021-02-09T06:30:00.000Z", "2021-02-23T06:30:00.000Z", "2021-02-16T06:30:00.000Z", "2020-12-08T06:30:00.000Z", "2020-12-15T06:30:00.000Z", "2020-12-02T06:30:00.000Z", "2020-12-09T06:30:00.000Z", "2020-12-16T06:30:00.000Z"];
const mapping = dateArray.reduce((initial, next) => {
const month = next.substring(5, 7);
const year = next.substring(0, 4);
const day = next.substring(8, 10);
initial[year] = initial[year] || {};
initial[year][month] = initial[year][month] || [];
initial[year][month].push(parseInt(day, 10));
return initial;
}, {});
const result = []
Object.keys(mapping).forEach(year => {
Object.keys(mapping[year]).forEach(month => {
result.push({
month,
year,
dates: mapping[year][month]
});
});
});
console.log(result);
One simple solution is to use an object to group by month and year like below:
const data = ["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z",
"2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z",
"2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z",
"2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z",
"2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z",
"2020-12-16T06:30:00.000Z"];
function groupDates(dates) {
const groupedDates = {};
dates.forEach(d => {
const dt = new Date(d);
const date = dt.getDate();
const year = dt.getFullYear();
const month = dt.getMonth() + 1;
const key = `${year}-${month}`;
if (key in groupedDates) {
groupedDates[key].dates = [...groupedDates[key].dates, date];
} else {
groupedDates[key] = {
year,
month,
dates: [date],
};
}
});
return Object.values(groupedDates);
}
console.log(groupDates(data));
Here is a pure javascript solution without using any library. It is based on a simple O(n^2) runtime. But if you like to use some libraries for like binary search you can reduce it to O(nlogn).
The trick is to brick this task into smaller task as I did with functions getMonthYear (to convert string to object), compare and addDate:
data = ["2021-01-05T06:30:00.000Z","2021-01-06T06:30:00.000Z","2021-01-20T06:30:00.000Z","2021-02-09T06:30:00.000Z","2021-02-23T06:30:00.000Z","2021-02-16T06:30:00.000Z","2020-12-08T06:30:00.000Z","2020-12-15T06:30:00.000Z","2020-12-02T06:30:00.000Z","2020-12-09T06:30:00.000Z","2020-12-16T06:30:00.000Z"];
function categorize(data) {
// 2021-01-05T06:30:00.000Z => {month:"01", year:"2021", date:"05"}
function getMonthYear(str) {
var datePart = str.toString().trim().split("T")[0];
var datePartArr = datePart.split("-");
return {month:datePartArr[1], year:datePartArr[0], date:datePartArr[2]};
}
// testing
//var ans = getMonthYear("2021-01-06T06:30:00.000Z");
//console.log(ans);
// comparing two items to see if they have the same year and month
function compare(item1, item2) {
return (item1.month == item2.month) && (item1.year == item2.year);
}
// testing
//var ans = compare({month:"04", year:"2021"}, {month:"03", year:"2021"});
//console.log(ans);
// adding a date to the list of dates
function addDate(dateList, dateNumber) {
for(var i in dateList) {
if (dateList[i] == dateNumber) return;
}
dateList.push(dateNumber);
}
// testing
/*var ans = [2,4];
addDate(ans, 4);
console.log(ans);*/
// Now lets build the answer by looping over
// --------------------------------------------
var list = []; // the final answer list
data.forEach(function(str){
var item = getMonthYear(str);
var itemMatched = false;
// now lopping over the list to see if it has any match
for(var i in list) {
if (compare(item, list[i])) { // matched found
itemMatched = true;
addDate(list[i].date, item.date);
break;
}
}
// item had no match, add it as a new item to list
if (!itemMatched) {
list.push({
month: item.month,
year: item.year,
date: [item.date]
});
}
});
return list;
}
var ans = categorize(data);
console.log(ans);
Here is link to jsfiddle

How can i remove employees from the array that have endDate property higher than current selected month?

The data is coming from Google Sheets API, hence employees.stratdate, employees.enddate etc.
I need to be able to display only the employees that used to work in a selected month. If they don't work anymore, but used to work then, they should be listed, if they stopped working before the selected month, they shouldn't be listed.
THERE ARE 2 SHEETS:
a) ONE HAS TWO COLUMNS YEAR AND A MONTH -->
2011 March -> reports
b) THE OTHER ONE HAS ON CONTAINING DATE FORATED AS:
03-24-2011 -> employees [startdate & enddate formated like this]
That's why that silly attempt of formatting ...
const {employees, reports} = this.props;
const monthsFormated = reports.map(item => {return item.month});
const yearsFormated = reports.map(item => {return item.year});
const employeeStart = employees.map(item => {return item.startdate});
const employeeEnd = employees.map(item => {return item.enddate});
const monthNamesToNumbers = () => {
let extraFormatting = [];
for (let i=0; i<monthsFormated.length; i++) {
extraFormatting.push(moment().month(monthsFormated[i]).format("M"));
}
return extraFormatting;
}
// FROMATING DATES COMING FROM EMPLOYEES-TEMPLATE
let finalReportsFormatting = _.zip(yearsFormated, monthNamesToNumbers())
.map((value) => {
let test;
return test = (value[1] + '-' + value[0])
});
let employeeArr = employees.map(item => {
return moment(item.startdate).format('M-YYYY')
})
let newArr = Array.from(finalReportsFormatting).map(item => {
return item
})
let testArr = [];
for (var i = 0; i < employeeArr.length; i++) {
for (var j = 0; j < newArr.length; j++) {
if (employeeArr[i] === newArr[j]) {
testArr.push(newArr[j])
}
}
}
const result = [];
employees.forEach(emp => {
if (testArr.some(item => moment(emp.startdate).format('M-YYYY') == item) &&
testArr.some(item => (moment(emp.enddate).format('M-YYYY') > item))) {
result.push(emp);
}
});
THANK YOU IN ADVANCE:)
how about simply adding the employees that correspond during the first loop:
employees.forEach(emp => {
if (testArr.some(item => moment(emp.startdate).format('M-YYYY') == item) &&
testArr.some(item => (moment(emp.enddate).format('M-YYYY') > item))) {
result.push(emp);
}
});
I hope this help you,
There is a method in javascript arrays that will help you. As MAP, that iterate every item on an array, exits the array method filter
On the last iteration you should use filter and map instead of the forEach
Something like this:
var filteredEmployees = employees.filter(function(){
// your filter here
}).map(...);
You can separate the callback in diferent functions to make your code more simple. Or you can separate the filter and the map in different declarations.
var filteredEmployees = employees.filter(function(){
// your filter here
});
var mapEmployees = filteredEmployees.map(...);
Maybe this code isn't that you are looking for, but for sure do your code more clear and easy to manage.

AngularJS or Moment JS Get Date Range from Start and End Date from an Array of Date Ranges then Flatten into one array

Based on example below, how do I get date ranges from these two arrays using AngularJS, Moment JS, or plain javascript and flatten it into one array of dates?
Essentially turn this array below:
[["10,01,17", "10,03,17"], ["11,02,17" , "11,04,17" ]]
Into this flattened array of all dates included in the date range calculation:
["10,01,17", "10/02/17", "10,03,17", "11,02,17" , "11,03,17", "11/04/17"]
Its not perfect, but you can get the gist form that. codepen
const days = [['10/03/17', '10/01/17'], ["11/02/17" , "11/04/17" ]]
const daysdiff = (d1, d2) => moment(d2).diff(moment(d1), 'days')
const dayRange = (day, count) => {
const res = []
for(let i = 0; i <= count; i++) {
res.push(moment(day).add(i, 'days').format('MM/DD/YYYY'));
}
return res
}
const newDays = days.map((pair) => {
const sorted = pair.sort();
const diff = daysdiff(sorted[0], sorted[1])
return dayRange(sorted[0], diff);
});
result = [...newDays[0], ...newDays[1]]
console.log(result)

Categories

Resources