skip to Main Content

I aim to extract all the leg information from the child objects and store it within the parent object under the "Legs" property. Each leg will be assigned its own index to maintain individuality and order within the collection.

This involves creating a mechanism, likely a recursive function, to traverse through the nested structure of child objects and gather their leg data. The collected leg information will then be organized and appended to the "Legs" property of the parent object, ensuring that each leg retains its unique index for reference. (rephrased using ChatGPT)

Here’s the structure of the original object:

- TripLeg
  - dateTime: "2023-11-30 11:10:00.000"
  - pickupLat: "31.4754464"
  - pickupLong: "74.4012975"
  - dropoffLat: "31.4715199"
  - dropoffLong: "74.3555422"
  - currentRideDistanceMeters: 7106
  - currentRideDistanceMiles: 4.415462326
  - currentRideDurationSeconds: "821s"
  - currentRideDurationMinutes: 13.683333333333
  - Legs
    - TripLeg
      - dateTime: "2023-11-30 11:13:00.000"
      - special_requirements: "20"
      - pickupLat: "31.4711631"
      - pickupLong: "74.3534321"
      - dropoffLat: "31.4754464"
      - dropoffLong: "74.4012975"
      - currentRideDistanceMeters: 8501
      - currentRideDistanceMiles: 5.282274871
      - currentRideDurationSeconds: "849s"
      - currentRideDurationMinutes: 14.15
      - Legs
        - TripLeg
          - dateTime: "2023-11-30 11:12:00.000"
          - special_requirements: "20"
          - pickupLat: "31.4715199"
          - pickupLong: "74.3555422"
          - dropoffLat: "31.4684957"
          - dropoffLong: "74.3556928"
          - currentRideDistanceMeters: 2192
          - currentRideDistanceMiles: 1.362045232
          - currentRideDurationSeconds: "601s"
          - currentRideDurationMinutes: 10.016666666667
          - Legs
            - TripLeg (empty)
    - TripLeg (same as the above)
    - TripLeg (same as the above)

Here’s what I am aiming to achieve:

- TripLeg
  - dateTime: "2023-11-30 11:10:00.000"
  - pickupLat: "31.4754464"
  - pickupLong: "74.4012975"
  - dropoffLat: "31.4715199"
  - dropoffLong: "74.3555422"
  - currentRideDistanceMeters: 7106
  - currentRideDistanceMiles: 4.415462326
  - currentRideDurationSeconds: "821s"
  - currentRideDurationMinutes: 13.683333333333
  - Legs
    - Leg1
    - Leg2
    .
    .
    .
    -Leg(n)

Here’s my recursive function code:

    foreach ($rides as $rideskey => $ride) {
        $Legs  = [];
        $index = 0;
        $this->flattenLegs($ride->Legs, $Legs, $index);
    }

    function flattenLegs($data, &$result, &$index) {
        foreach ($data as $item) {
            $leg = $item->Legs ?? null;
            unset($item->Legs);
    
            $result["Legs"][$index++] = $item;
    
            if ($leg) {
                $this->flattenLegs($leg, $result, $index);
            }
        }
    }


The error I am receiving:

ErrorException
Undefined property: stdClass::$Legs

Error on:

$this->flattenLegs($ride->Legs, $Legs, $index);

If you are wondering how I got the object like that in the first place, so here’s the code for it.

    private function updateRouteEstimations($tripData, $estimations)
    {
        $estimationCollection = collect($estimations);
    
        foreach ($tripData as $tripkey => $trip) {
                $nextPickups = $estimationCollection->where('destinationIndex', $tripkey)->where('originIndex','!=' ,$tripkey);
    
                $currentRideEstimation = $estimationCollection
                    ->where('originIndex', $tripkey)
                    ->where('destinationIndex', $tripkey)
                    ->first();

                $trip->currentRideDistanceMeters    = $currentRideEstimation->distanceMeters;
                $trip->currentRideDistanceMiles     = $trip->currentRideDistanceMeters * 0.000621371;
                $trip->currentRideDurationSeconds   = $currentRideEstimation->duration;
                $trip->currentRideDurationMinutes   = (int)str_replace('s', '', $currentRideEstimation->duration) / 60;

                $nextNearestEstimation        = $this->findNextNearestRide($nextPickups, $trip, $tripkey);
                $trip->Legs[] =  $tripData[$nextNearestEstimation->originIndex];
        }
    
        return $tripData;
    }

2

Answers


  1. Chosen as BEST ANSWER

    Update Spent another 2 days trying to fix it but all in vain. But I still somehow got the desired output. I changed the updateRouteEstimations() so now it returns the data the way I want it. Pasting the code here for reference.

        private function updateRouteEstimations($tripData, $estimations)
        {
                $newPool = [];
                $estimationCollection = collect($estimations);
                $tripDataCollection = collect($tripData);
                $newPool[$tripData[0]->care_dispatch_tripleg_id] = [];
                $newPool[$tripData[0]->care_dispatch_tripleg_id]['nextNearestRides'] = [$tripData[0]->care_dispatch_tripleg_id];
            
                $count = count($tripData);
                $i = 0;
                $previous = 0;
                $alreadyProcessed = [];   
                $continue = true;
                while($continue){
                $minDistance = $estimationCollection
                                ->where('originIndex', '!=', $i)
                                ->where('destinationIndex', $previous)
                                ->whereNotIn('originIndex', $alreadyProcessed)
                                ->min('distanceMeters');
        
                $temp = $estimationCollection
                         ->where('destinationIndex', $previous)
                         ->where('originIndex', '!=', $i)
                         ->where('distanceMeters', $minDistance)
                         ->whereNotIn('originIndex', $alreadyProcessed)
                         ->first();
                $previous = $i;
                $alreadyProcessed[] = $previous;
                if(!empty($temp)){
                   $triplegId = $tripData[$temp->originIndex]->care_dispatch_tripleg_id;
                   $nextFindQuery = $tripDataCollection->where('care_dispatch_tripleg_id',$triplegId);
                   $nextFindGet = $nextFindQuery->first();
                   $newPool[$tripData[0]->care_dispatch_tripleg_id]['nextNearestRides'][] = $triplegId;
                   $i = $nextFindQuery->keys()->first();
                }else{
                   $continue = false;
                }
             }
            return $newPool;
        }
    

  2. I rewrote the function to check if the Legs property exists, if not, assign null and then wrote a foreach showing how to call the function, hope that helps.

       function flattenLegs($data, &$result, &$index) {
            foreach ($data as $item) {
                $leg = $item->Legs ?? null;
                unset($item->Legs);
                $result["Legs"][$index++] = $item;
        
                if ($leg) {
                    $this->flattenLegs($leg, $result, $index);
                }
            }
        }
        
        foreach ($rides as $rideskey => $ride) {
            $Legs  = [];
            $index = 0;
            if (isset($ride->Legs)) {
                $this->flattenLegs($ride->Legs, $Legs, $index);
            }
        }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search