2

I have two arrays $patients and $escorts.

These arrays represent hospital stays for various patients and escorts. Escorts have a ['Escort']['id'] value that is associated with the ID of a Guest (Patient).

My goal is two take the Patients and Escorts arrays and combine them into a results array that can be used for printing (either a table, or creating an excel file).

Patients may have multiple stays, and a Patient may also have multiple Escorts escorting them.

$patients = [
     Patient A,
     Patient B,
     Patient B
     Patient C,
     Patient D,
     Patient E
 ];

 $escorts = [
     Escort for Patient B,
     Escort 1 for Patient C,
     Escort 2 for Patient C,
     Escort for Patient E 
 ];

I am trying to get the $newResults array in the following order:

$newResults = [
   Patient A,
   Patient B,
   Patient B,
   Escort for Patient B,
   Patient C,
   Escort for Patient C,
   Escort for Patient C,
   Patient D,
   Patient E,
   Escort for Patient E,
]

However, when I'm done iterating through both arrays I have leftover $escort elements that haven't been added after their $patient counterpart, yet going through the data the Patient's ['Guests']['id'] and the Escort's ['Escort']['id'] match, so I'm not sure why they're not being included.

The code I am using is:

 $lastPatientID = 0;
 foreach($patients as $pkey => $patient) {
    if($lastPatientID == 0) {
        $lastPatientID = $patient['Guests']['id'];
    }

    if($patient['Guests']['id'] == $lastPatientID) {
        // Add Patients Next Accommodation
        $newResults[] = $patient;
    } else {
        $theseEscorts = [];

        foreach($escorts as $ekey => $escort) {
            if($escort['Escort']['id'] == $lastPatientID) {
                $theseEscorts[] = $escort;
                unset($escorts[$ekey]);
            }
        }

        // Print the escorts for the Last Patient.
        foreach($theseEscorts as $anEscort) {
            $newResults[] = $anEscort;
        }

        // This Patient is different than last. Print New Patient.
        $newResults[] = $patient;
    }

    $lastPatientID = $patient['Guests']['id'];
}

// Clear any remaining escorts that match the last patient.
foreach($escorts as $escort) {
     if($escort['Escort']['id'] == $lastPatientID) {
         $newResults[] = $escort;
     } else {
          // NOTE:: THIS SHOULDN'T HAPPEN UNLESS DATA IS BAD!
          error_log("Orphaned Escort: \n" . print_r($escort, TRUE) );
     }
 }

I must be making some logic mistake with this, although I'm not sure where.

Any advice is much apprecaited!

2
  • Please go to 3v4l.org and put your sample array and code then hit "Eval" and post the link here. Commented Sep 15, 2015 at 16:20
  • 3v4l.org/QOEco As you can see in the Output for 5.4.0 The resulting $newResults array is ordered: 0 - Jane Smith 1 - John Smith 2 - Jane Doe This is as it should be. But in some instances (and I'm not sure what's causing it so I can't reproduce it) the results would be: 0 - Jane Smith 1 - Jane Doe (John Smith isn't getting added) Commented Sep 15, 2015 at 17:04

2 Answers 2

1

It's hard to tell from what you've given here. We discussed this on IRC and I proposed this solution given the actual structure of your arrays.

Features:

  • Each line in the result array is either one patient or one escort for that patient
  • The type will tell you which it is
  • The rec will give you all the rest of the information
  • Building the escortMap ensures you don't have to loop through all the escorts for each patient.

$escorts = [];

$newResults = [];

$escortMap = [];

foreach($escorts as $escortId => $e){
    $escortMap[$e->Escort->id][] = $escortId;
}

foreach( $patients as $patientId => $p ){

    $newResults[] = array(
        'type' => 'patient',
        'rec' => $p
    );

    foreach( $escortMap[$patientId] as $escortId){
        $e = $escorts[$escortId];
        if($e->Escort->id == $patient->Guest->id){ // or some other test to see if this escort matches this patient
            $newResults[] = array(
                'type' => 'escort for ' . $patientId,
                'rec' => $e
            );
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

I figured out the solution to this. The cause of the problem was some bad data, instances where the Escort was associated with a Patient who didn't have an entry in the database table for accommodations.

My solution to this was to implement a uasort() function to put the rows I wanted in the correct order:

uasort($newResults, function($a, $b) {
    $aSortOn = ($a['Accommodations']['purpose_id'] != 4 ? $a['Guests']['lastName'] : $a['Escort']['lastName']);
    $bSortOn = ($b['Accommodations']['purpose_id'] != 4 ? $b['Guests']['lastName'] : $b['Escort']['lastName']);

    if($aSortOn == $bSortOn) {
        $aSortOn = ($a['Accommodations']['purpose_id'] != 4 ? $a['Guests']['firstName'] : $a['Escort']['firstName']);
        $bSortOn = ($b['Accommodations']['purpose_id'] != 4 ? $b['Guests']['firstName'] : $b['Escort']['firstName']);
    }

    if($aSortOn == $bSortOn) {
        // Sort to Make Sure Patient (Purpose_id != 4) is above (Purpose_id == 4) in results.
        if($a['Accommodations']['purpose_id'] != 4 && $b['Accommodations']['purpose_id'] == 4) {
            return 0;
        } else {
            return 1;
        }

    } else {
        return ($aSortOn < $bSortOn) ? -1 : 1;
    }
});

If the guest is a Patient, it will sort them by LastName, FirstName, and if they are an Escort it sorts them by the LastName, FirstName of the person they are escorting.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.