Separate array after each second comma - javascript

I got an array from a CMS that is poorly formatted which I want to reformat to an array of objects.
let daysOffArray = ["2022-08-22, 08:00 - 14:00","2022-08-23, 08:00 - 13:00"];
Expected result after separating the array:
let daysOff = [{
date: "2022-08-22",
time: 08:00 - 14:00
},
{
date: "2022-08-23",
time: 08:00 - 13:00
}];
How can I separate the array daysOffArray for each second comma and then separate the two new arrays after each comma?

You can use array destructuring and the object literal property value shorthand for a more concise solution and better readability.
daysOffArray.map(item => {
const [date, time] = item.split(', ');
return { date, time };
});

// Initial object
var daysOffArray = [
'2022-08-22, 08:00 - 14:00',
'2022-08-23, 08:00 - 13:00',
];
// An empty array for the formatted object
var daysOffFormatted = [];
// Splitting and formatting the array
daysOffArray.forEach((daysOff) => {
var date = daysOff.split(',')[0].trim();
var time = daysOff.split(',')[1].trim();
// Adding formatted object to the array
daysOffFormatted.push({ date, time });
});
console.log(daysOffFormatted);

Use String#split and Array#map:
let daysOff = daysOffArray.map(item => {
const data = item.split(", ");
return { date: data[0], time: data[1] };
});

let daysOffArray = ["2022-08-22, 08:00 - 14:00","2022-08-23, 08:00 - 13:00"];
let daysOff = [];
daysOffArray.forEach((item) => {
daysOff.push({ date: item.split(",")[0], time: item.split(",")[1] });
});
console.log(daysOff);

let daysOff = daysOffArray.map((datetime)=>{
const [date, time] = datetime.split(',');
return {date, time: time.trim()};
});

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 return specific year from Date array ? react

I've got a dates array and I wanted to create a function that returns all the dates from 2014 or 2015 depending on what the user clicks
i tried using substring(), although that gives me an array of the 2014 dates, it also returns 2 undefined's which I dont want. How would I return an array of only 2014 dates?
const datefunc = () => {
const date = ['2014-4-4', '2014-5-4', '2015-4-4', '2015-3-4']
const dates = date.map((d) => {
if (d.substring(0, 4) === '2014') {
return d;
}
})
console.log(dates)
}
datefunc()
Array.map modifies each element in an array => when you run date.map and only return a value if the date starts with '2014', all the other values in the array will become undefined.
Array.filter filters the elements in an array based on a predicate => when running date.filter, all the elements for which the predicate is false will be excluded in the returned array.
Changing your code to this should work:
const datefunc = () => {
const date = ['2014-4-4', '2014-5-4', '2015-4-4', '2015-3-4'];
const dates = date.filter((d) => d.substring(0, 4) === '2014');
// You could also use this
// const dates = date.filter((d) => d.startsWith('2014'));
console.log(dates);
}
datefunc();
If your dates aren't all of the same form, but all valid date strings you could also tranfsorm them into Date values and then filter them like this:
const datefunc = () => {
const date = ['2014-4-4', '2014-5-4', '2015-4-4', '2015-3-4'];
const dates = date
.map((d) => new Date(d))
.filter((d) => d.getFullYear() === 2014);
console.log(dates);
}
datefunc();
const datefunc = () => {
const date = ['2014-4-4', '2014-5-4', '2015-4-4', '2015-3-4']
const dates = date.filter((d) => d.substring(0, 4) === '2014')
console.log(dates)
}
datefunc()
A more robust way to do this would be to convert string to date. Also, since you need to filter out dates, map wouldn't really work here. Even for false conditions, even though you are not returning anything, you end up returning undefined anyways. That's why those two undefined values
const datefunc = () => {
const date = ['2014-4-4', '2014-5-4', '2015-4-4', '2015-3-4']
const targetYears = [2014, 2015]; // Add the years here which you want to filter on
const dates = date.filter((d) => {
const curYear = new Date(d).getFullYear();
return targetYears.includes(curYear);
})
console.log(dates)
}
datefunc()
You can add the years you want in the filteredYears array
const datefunc = () => {
const dates = ['2014-4-4', '2014-5-4', '2015-4-4', '2015-3-4']
const filteredYears = [2014];
const filteredDates = dates.filter(date => filteredYears.includes(new Date(date).getFullYear()));
console.log(filteredDates)
}
datefunc()
You may convert datestring to date type first, then make use "filter()" to get particular year date. Hopefully this helps you!
date = ["2014-4-4", "2014-5-4", "2015-4-4", "2015-3-4"];
convertedDate: Date[] = [];
getYearList() {
this.date.forEach(x => {
this.convertedDate.push(new Date(x));
});
this.convertedDate = this.convertedDate.filter(
x => x.getFullYear() == 2014
);
console.log(this.convertedDate);
}
const datesInYear = (dates, year) => {
return dates.filter((x) => x.includes(year));
};
const dates = ["2014-4-4", "2014-5-4", "2015-4-4", "2015-3-4"];
console.log(datesInYear(dates, "2014"));

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

Getting loop when checking Array Object for match and pushing object when none found

Here is my code:
function createMatchList(data) {
var matchArray = [];
for (var i = 0; i < initialData.length; i++) {
var listData = cleanData(initialData[i][data]);
if (matchArray.length) {
for (var a = 0; a < matchArray.length; a++) {
if (matchArray[a][data] == listData) {
matchArray[a].Count = matchArray[a].Count + 1;
} else {
// THIS CAUSES LOOP
matchArray.push({ [data]: listData, "Count": 1 });
}
}
} else {
matchArray.push({ [data]: listData, "Count": 1 });
}
}
}
Essentially, this appears to work outside of when a matching object isn't found, I have an else to push that object to the array and it causes a loop.
I'm not sure why this would happen and I'm totally lost..
I have an initial if/else to see if the array is empty, if it is empty, push the initial object into the array, past this point if the array isn't empty, I check the array using a for loop and the if statement works, but my else statement causes the loop. If I were to take that matchArray.push({ [data]: listData, "Count": 1 }); out of the else statement and just console.log something, it would successfully log for each additional iteration in the first for loop for the initialData.
And just to give an idea of what the array looks like with an object in it:
[
{
Date: "27 June 1911",
Count: 1
}
]
My goal is to search the Array for matching Dates and if there is a match, don't push to the Array but instead update the Count. The reason for this is I have a huge raw JSON file with duplicates and I'm trying to create a new data source removing duplicates but counting the occurrences.
Thanks
Use Set and Array.filter():
[...new Set(dates)].map(date => ({
date,
count: dates.filter(currDate => date === currDate).length
}));
Note: By convention object keys should be lowercased, date and not Date.
Or if you feel brave:
const counts = {};
dates.forEach(date => (counts[date] = (counts[date] || 0) + 1));
const dates = [
'27 June 1911',
'27 June 1952',
'27 March 1911',
'27 June 1952',
'24 June 1911',
'27 June 1952'
];
const datesCount = [...new Set(dates)].map(date => ({
date,
count: dates.filter(currDate => date === currDate).length
}));
console.log('datesCount', datesCount);
const counts = {};
dates.forEach(date => (counts[date] = (counts[date] || 0) + 1));
const dateCount2 = Object.entries(counts).map(([date, count]) => ({
date,
count
}));
console.log('dateCount2', dateCount2);
// Make unique array of dates.
const datesSet = [...new Set(dates)];
// Count by filtering the array and getting it's length.
const datesCount = datesSet.map(date => ({
date,
count: dates.filter(currDate => date === currDate).length
}));
How important is performance and are you using >= 2015? If so, you could just map instead and reduce some code complexity like this answer:
const counts = new Map([...new Set(a)].map(
x => [x, a.filter(y => y === x).length]
));
Then to get the count you would just call:
counts.get(x)
In the case where you need to store it in an object that looks exactly as you've outlined above, I would do something like:
let unique = Set(dates);
var matchArray = [];
unique.forEach(function (date) {
matchArray.push({
"Date": date,
"Count": dates.filter(x => x === date).length
});
});

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