Home > Back-end >  Re-ordering one array of objects based on data from another array in Javascript (React)
Re-ordering one array of objects based on data from another array in Javascript (React)

Time:03-31

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:

enter image description here

And I have an array of objects of all consultants:

enter image description here

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()]);

  • Related