I've been tasked with taking in an array of objects representing 'consultants' with ids for each and re-arranging them based on the most recent selected consultants of a session booking.
So I have an array of objects of upcoming sessions with the most recent to last:
And I have an array of objects of all consultants:
So therapistId
of 'upcomingSessions' match id
of 'consultants'
I wrote a method that pulls the therapists from the 'upcomingSessions' into a new array and then concats the remaining, keeping the order of the 'upcomingSessions' therapists.
So the user will see the most recent selected therapists from a dropdown menu.
The method I wrote works but it has a nested forEach()
loop because filter()
only selected the used consultants but doesn't keep the order.
Here's the method:
const handleUpdatedConsultantList = () => {
// first capture the ids of chosen therapists
const consultantIds = upcomingSessions.map((us) => us.therapistId)
// create an array of remaining therapists
const remainingConsultants = consultants.filter(
(c) => !consultantIds.includes(c.id),
)
// empty array to push in the entire object of each chosen therapist
const recentConsultants: ConsultantType[] = []
// method to push in therapists by most recent
consultantIds.forEach((c) => {
consultants.forEach((co) => {
if (c === co.id) {
recentConsultants.push(co)
}
})
})
// concat most recent with remaining
return recentConsultants.concat(remainingConsultants)
}
My question is, is this the best way to implement this? Nested loops always make me un-easy but maybe it's the only way for keeping the order of the selected consultants?
This gets the filtered chosen consultants but sorts the ids from least to greatest instead of the order that was selected:
const selectedConsultants = consultants.filter((c) => [313, 312, 311, 302].includes(c.id))
CodePudding user response:
I think you can more directly get your list of recentConsultants
by using a find()
lookup when mapping over the consultantIds
.
const handleUpdatedConsultantList = () => {
// first capture the ids of chosen therapists
const recentConsultantIds = upcomingSessions.map((us) => us.therapistId);
// map through ids and connect with consultant profiles
const recentConsultants = recentConsultantIds.map((id) =>
consultants.find((c) => c.id === id)
);
// create an array of remaining therapists
const remainingConsultants = consultants.filter(
(c) => !recentConsultantIds.includes(c.id)
);
// concat most recent with remaining
return recentConsultants.concat(remainingConsultants);
};
CodePudding user response:
A Map will do the job just fine:
const upcomingSessions = [
{therapistId: 5},
{therapistId: 8},
{therapistId: 9},
{therapistId: 7}
];
const consultants = [
{id: 1},
{id: 2},
{id: 3},
{id: 5},
{id: 6},
{id: 7},
{id: 8},
{id: 9},
{id: 10},
{id: 11},
{id: 12}
];
const recentConsultants = new Map(upcomingSessions.map(us => [us.therapistId, ]));
consultants.forEach(c => recentConsultants.set(c.id, c));
console.log([...recentConsultants.values()]);