Display Parent-Child Posts in specific order by comparing IDs in array

I think you’ll just need to loop the loop and first build a helper array to contain the hierarchy, then work with that to print out any necessary html. Caching the resulting helper array to a transient might be a good idea to save processing time.

// is there a transient?
$transient = get_transient( "parent_children_ids_{$post_id}" );

if ( ! $transient ) {
  // initial query
  $all_services = new WP_Query( $args );
  
  // first sort found posts to a helper associative array
  $posts_by_id = array();
  foreach ($all_services->posts as $service) {
    $posts_by_id[$service->ID]$service;
  }
  
  // create hierarchy array
  $parent_children_ids = array();
  // track parents IDs that are not in found posts
  $missing_parent_ids = array();
  
  // WP_Query by default returns array of WP_Post objects
  // WP_Post has a property post_parent, which is the ID of the parent post, if such is set
  foreach ($all_services->posts as $service) {
    // add parents as top level keys
    if ( ! $service->post_parent ) {
      if ( ! isset($parent_children_ids[$service->ID]) ) {
        $parent_children_ids[$service->ID] = array();
      }
      continue;
    }
  
    // add the parent to the array, if it hasn't been added already
    if ( ! isset( $parent_children_ids[$service->post_parent] ) ) {
      $parent_children_ids[$service->post_parent] = array();
    }
  
    // should the parent be queried
    if ( ! isset( $posts_by_id[$service->post_parent] ) ) {
      $missing_parent_ids[] = $service->post_parent;
    }
  
    // append the post to the child array
    $parent_children_ids[$service->post_parent][] = $service->ID;
  }
  
  // query the missing parent posts
  if ( $missing_parent_ids ) {
    $missing_parents = new WP_Query('post__in' => $missing_parent_ids);
    // push the found posts to the posts helper array
    foreach ($missing_parents->posts as $service) {
      $posts_by_id[$service->ID]$service;
    }
  }

  // do some further sorting, if needed..
  
  // perhaps save the $parent_children_ids to an transient
  // to skip the previous processing for a suitable length of time
  // remember to clear the transient when the source data changes to have the transient rebuilt
  set_transient( "parent_children_ids_{$post_id}", $parent_children_ids, DAY_IN_SECONDS );
} else {
  $parent_children_ids = $transient;
}

// loop the parents and chilrend array
foreach ($parent_children_ids as $parent_id => $child_ids) {
  $parent = $posts_by_id[$parent_id];
  // parent code..

  foreach ($child_ids as $child_id) {
    $child = $posts_by_id[$child_id];
    // child code...
  }
}

tech