I have an array of data like so:
let arrayData =[
{
"category": "2019-07-24",
"total": 1,
"Col 1": 100
},
{
"category": "2018-11-12",
"total": 3,
"Col 1": 101
},
{
"category": "2019-07-11",
"total": 1,
"Col 1": 200
},
{
"category": "2019-08-11",
"total": 1,
"Col 1": 153
},
{
"category": "2019-09-25",
"total": 1,
"Col 1": 198
}
]
How can I check if every 'category' value inside the array is in the format YYYY-MM-DD? And if so, re-order the objects inside the array by earliest date?
I know that I can use regex like so to check for individual dates:
checkIfDateIsInRightFormat() {
// Is this the best way?
const regex = /^\d{4}-\d{2}-\d{2}$/;
if (dateStr.match(regex) === null) {
return false;
}
const date = new Date(dateStr);
const timestamp = date.getTime();
if (typeof timestamp !== 'number' || Number.isNaN(timestamp)) {
return false;
}
return date.toISOString().startsWith(dateStr);
}
and then I can do this:
let arrayOfItems = []
this.arrayData.foreach(item => {
arrayOfItems.push(this.checkIfDateIsInRightFormat(item))
})
let result = arrayOfItems.every(element => {
if (element === array[0] && element === true) {
return true;
}
});
if(result === true) {
// Here I'll order the objects in arrayData by earliest date in 'category'
arrayData.sort(
(objA, objB) => Number(objB.category) - Number(objA.category),
);
}
However, it doesn't work as intended. How would I be able to achieve the right result?
Based on the arrayData above, the result should be:
let newArrayData =[
{
"category": "2018-11-12",
"total": 3,
"Col 1": 101
},
{
"category": "2019-07-11",
"total": 1,
"Col 1": 200
},
{
"category": "2019-07-24",
"total": 1,
"Col 1": 100
},
{
"category": "2019-08-11",
"total": 1,
"Col 1": 153
},
{
"category": "2019-09-25",
"total": 1,
"Col 1": 198
}
]
Otherwise if I have something like this:
let exampleArrayData =[
{
"category": "2018-11-12",
"total": 3,
"Col 1": 101
},
{
"category": "ABC",
"total": 1,
"Col 1": 200
},
]
It would stop at finding out that they are not all dates. result = false.
CodePudding user response:
Simplest way I think:
let newArrayData = false;
let arrayData =[
{
"category": "2019-07-24",
"total": 1,
"Col 1": 100
},
{
"category": "2018-11-12",
"total": 3,
"Col 1": 101
},
{
"category": "2019-07-24",
"total": 1,
"Col 1": 200
},
{
"category": "2019-08-11",
"total": 1,
"Col 1": 153
},
{
"category": "2019-09-25",
"total": 1,
"Col 1": 198
}
];
if (arrayData.every(x => new Date(x.category) !== "Invalid Date" && !isNaN(new Date(x.category)))){
newArrayData = arrayData.slice().sort((a, b) => new Date(a.category) - new Date(b.category));
}
console.log(newArrayData);
.every() checks whether all items fulfill a condition.
By trying to convert the strings into a date, we can check whether they result in "Invalid Date" (which is returned by the new Date object in case of an invalid date) and if it is a number (ms since January 1, 1970). Now if you really want to make sure, that the strings are EXACTLY in YYYY-MM-DD format, then yes, you need regex, see: Regex date validation for yyyy-mm-dd
.slice() is only there to first make a copy of the array and can be omitted if you don't care about manipulating the original array, which .sort() otherwise does by default.
CodePudding user response:
To check if every category
value in the arrayData
is in the format YYYY-MM-DD, you can use a regular expression /^\d{4}-\d{2}-\d{2}$/
to test if each value matches the format. If the value matches the format, you can then convert it to a Date object and sort the array of objects based on the Date
object
const arrayData = [{category: '2019-07-24',total: 1,'Col 1': 100,},{category: '2018-11-12',total: 3,'Col 1': 101,},{category: '2019-07-11',total: 1,'Col 1': 200,},{category: '2019-08-11',total: 1,'Col 1': 153,},{category: '2019-09-25',total: 1,'Col 1': 198,},]
const dateRegex = /^\d{4}-\d{2}-\d{2}$/
const result = arrayData
.filter((obj) => dateRegex.test(obj.category))
.sort((a, b) => new Date(a.category) - new Date(b.category))
console.log(result)