Reputation: 704
I have an array of objects I need to filter through and return only the objects closest to today. The issue I'm having is that it's returning the June date and not the one in May. here's the code I'm using:
const findClosest = (data, accessor, target = Date.now()) =>
data.reduce((prev, curr) => {
const a = Math.abs(accessor(curr).getTime() - target);
const b = Math.abs(accessor(prev).getTime() - target);
return a - b < 0 ? curr : prev;
});
const getClosestFromDate = (array, key, date) => {
let arr = array.filter((e) => e[key] == date);
return arr;
};
const sampleData = [{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"is_swappable": true,
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"next_charge_scheduled_at": "2022-05-23T00:00:00",
"order_day_of_month": null,
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-07-23T00:00:00",
"order_day_of_month": null,
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-05-23T00:00:00",
"order_day_of_month": null,
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-05-23T00:00:00",
"order_day_of_month": null,
},
{
"next_charge_scheduled_at": "2022-07-23T00:00:00",
"order_day_of_month": null,
},
];
const processDateString = (dateString) => {
let date = new Date(dateString);
let year = date.getFullYear();
let month = date.getMonth();
console.log(date.toString());
return new Date(year, month + 1, date);
};
const closest = findClosest(sampleData, ({
next_charge_scheduled_at
}) => processDateString(next_charge_scheduled_at), "2022-05-10T03:03:42");
console.log(closest.next_charge_scheduled_at);
console.log(getClosestFromDate(sampleData, "next_charge_scheduled_at", closest.next_charge_scheduled_at));
I got this code from one of the other questions, but for some reason even after trying multiple times to add or subtract from the month variable, I am unable to return the correct date. I'd really appreciate help on this.
Upvotes: 0
Views: 306
Reputation: 28236
You were making life too hard for yourself:
(I revised my answer after reading OP's latest comment.)
The const acc
is a utility function(obj)
that will grab the next_charge_scheduled_at
property of the obj
, turn it into a date
object and then return its .getTime()
value.
findClosest(sampleData,acc)
returns a single object of the given sampleData
array closest to the target time (Date.now()
). I then store the .getTime()
value of this element in the constant closest
and use it again to filter through the original input array:
const sampleData = [{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"is_swappable": true,
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-06-23T00:00:00",
},
{
"next_charge_scheduled_at": "2022-05-23T00:00:00",
"order_day_of_month": null,
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-07-23T00:00:00",
"order_day_of_month": null,
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-05-23T00:00:00",
"order_day_of_month": null,
},
{
"max_retries_reached": 0,
"next_charge_scheduled_at": "2022-05-23T00:00:00",
"order_day_of_month": null,
},
{
"next_charge_scheduled_at": "2022-07-23T00:00:00",
"order_day_of_month": null,
},
];
const
findClosest = (data, accessor, target = Date.now()) =>
data.reduce((prev, curr) => {
const a = Math.abs(accessor(curr) - target);
const b = Math.abs(accessor(prev) - target);
return a - b < 0 ? curr : prev;
}),
acc=obj=>new Date(obj.next_charge_scheduled_at).getTime(),
closest=acc(findClosest(sampleData,acc));
console.log(sampleData.filter(d=>acc(d)===closest));
The following version is even shorter and avoids the repeated calcuation of Date
objects:
function getClosest(arr){
const trg=Date.now()
times=sampleData.map((d,i)=>[new Date(d.next_charge_scheduled_at).getTime(),i]),
closest=times.reduce((p,c) => Math.abs(c[0]-trg) < Math.abs(p[0]-trg) ? c : p)[0];
return times.reduce((a,[t,i])=>(t==closest&&a.push(arr[i]),a),[]);
}
getClosest()
uses a temporary array times
to store the calculated .getTime()
value and the index i
for each object. After finding the closest time to Date.now()
the times
array is then -reduce()
d in order to compile the results from the original input array arr
.
Upvotes: 2