I have an array which has multiple properties like country, state, phone no. My question is that I want to make the state as heading for the elements having the same countries like:

   California (This should be heading)
   Los Angeles
   San Diego
   San Francisco

My array is as follows:

Array
    (
        [0] => Array
            (
                [id] => 14
                [post_id] => 319
                [location] => Atlanta, GA
                [address] => 161 Racetrack Rd., McDonough
                [city] => Atlanta
                [state] => Georgia
                [state_code] => GA
                [country] => USA
                [zipcode] => 30253
                [service_zipcode] => 
                [phone] => 
                [fax] => 
                [email] => 
                [facebook] => 
                [twitter] => 
                [linkedin] => 
                [gplus] => 
                [latitude] => 
                [longitude] => 
                [url] => 
                [created_at] => 2019-04-22 07:22:55
                [updated_at] => 2019-04-22 07:26:31
            )

        [1] => Array
            (
                [id] => 16
                [post_id] => 321
                [location] => Augusta, Georigia
                [address] => 1446 Harper Street
                [city] => Augusta
                [state] => Georigia
                [state_code] => GA
                [country] => USA
                [zipcode] => 
                [service_zipcode] => 
                [phone] => 
                [fax] => 
                [email] => 
                [facebook] => 
                [twitter] => 
                [linkedin] => 
                [gplus] => 
                [latitude] => 
                [longitude] => 
                [url] => 
                [created_at] => 2019-04-22 07:29:33
                [updated_at] => 2019-04-22 07:32:25
            )

        [2] => Array
            (
                [id] => 12
                [post_id] => 317
                [location] => Savannah, Georgia
                [address] => 834 Northside Dr. East
    Statesboro
                [city] => Savannah
                [state] => Georgia
                [state_code] => GA
                [country] => USA
                [zipcode] => 30458
                [service_zipcode] => 
                [phone] =>
                [fax] => 
                [email] => 
                [facebook] => 
                [twitter] => 
                [linkedin] => 
                [gplus] => 
                [latitude] => 
                [longitude] => 
                [url] => 
                [created_at] => 2019-04-22 07:15:43
                [updated_at] => 2019-04-22 07:18:11
            )

    )

So when there are cities having the same state should display state as heading for the first time. My array has only data for only one state, but do consider it for multiple states. Is there any way I can make a unique heading for this?

Update: My code is

<div class="row">
            <div class="col-md-12 contentside">



                    <div class="locations-container">
                       <?php 
                        global $wpdb;

                        $querystr = "
                            SELECT DISTINCT meta_value 
                            FROM $wpdb->postmeta 
                            WHERE meta_key = 'state_code' 
                            ORDER BY meta_value ASC
                        ";

                        $us_states = $wpdb->get_results( $querystr );
                        //echo "<pre>"; print_r($us_states); echo "<pre>";
                        foreach($us_states as $us_state) { ?>
                            <?php $locations = \abc\Helper\Location::getLocationsByState($us_state->meta_value); ?>
                            <h2>Here I want to display heading for state but it is outside loop</h2>
                            <?php //echo "<pre>"; print_r($locations); echo "</pre>"; ?>
                            <?php foreach($locations as $location): ?>
                                <div class="location-single">
                                    <h3>Mosquito Hunters of <?php echo $location['location']; ?></h3>
                                    <div class="location-inner">
                                        <img src="/wp-content/uploads/2019/04/eco-freeze-bed-bugs.jpg" alt=" ">
                                        <p> <?php echo $location['city'] ?>, <?php echo $location['state_code'] ?><br /> 
                                        <a href="mailto:<?php echo $location['email'] ?>"><?php echo $location['email'] ?></a><br />
                                        <a href="tel:<?php echo $location['phone'] ?>"><?php echo $location['phone'] ?></a></p>
                                        <a href="<?php echo $location['url'] ?>" class="btn">Learn about this location</a>
                                    </div>
                                </div>
                            <?php endforeach; ?>
                       <?php } ?>
                    </div>
            </div>
        </div>

2 Answers

2
Andreas On Best Solutions

If you use array_column you can get a flat array with state as value and city as key.
Then sort the array with asort to preserve keys and sort them by state.

Keep track of the state when it changes and echo the cities below the state.

$arr = array_column($locations, "state", "city");
asort($arr);
$prev = null;

foreach($arr as $city => $state){
    if($state != $prev){
        echo PHP_EOL . PHP_EOL . $state . PHP_EOL;
        $prev = $state;
    }
    echo "---" . $city . PHP_EOL;
}

https://3v4l.org/gfcia

Example output:

Georgia
---Atlanta
---Savannah


Georigia
---Augusta


Texas
---Huston
0
Pupil On

Steps to implement:

1) Please loop over your current array.

2) Create a new blank array.

3) Append to new array with country as key,

4) Append to new array with state as key,

Now, loop over new array and print country and state on a separate line.

<?php
$locations = Array(
        Array
            (
                'id' => 14,
                'post_id' => 319,
                'location' => 'Atlanta, GA',
                'address' => '161 Racetrack Rd., McDonough',
                'city' => 'Atlanta',
                'state' => 'Georgia',
                'state_code' =>'GA',
                'country' => 'USA',
                'zipcode' => 30253,
                'service_zipcode' => '',
                'phone' => '',
                'fax' => '',
                'email' => '',
                'facebook' => '',
                'twitter' => '',
                'linkedin' => '',
                'gplus' => '',
                'latitude' => '',
                'longitude' => '',
                'url' => '',
                'created_at' => '2019-04-22 07:22:55',
                'updated_at' => '2019-04-22 07:26:31',
            ),
            Array
            (
                'id' => 16,
                'post_id' => 321,
                'location' => 'Augusta, Georigia',
                'address' => '1446 Harper Street',
                'city' => 'Augusta',
                'state' => 'Georigia',
                'state_code' => 'GA',
                'country' => 'USA',
                'zipcode' => '',
                'service_zipcode' => '',
                'phone' => '',
                'fax' => '',
                'email' => '',
                'facebook' => '',
                'twitter' => '',
                'linkedin' => '',
                'gplus' => '',
                'latitude' => '',
                'longitude' => '',
                'url' => '',
                'created_at' => '2019-04-22 07:29:33',
                'updated_at' => '2019-04-22 07:32:25',
            ),
            Array
            (
                'id' => 12,
                'post_id' => 317,
                'location' => 'Savannah, Georgia',
                'address' => '834 Northside Dr. East, Statesboro',
                'city' => 'Savannah',
                'state' => 'Georgia',
                'state_code' => 'GA',
                'country' => 'USA',
                'zipcode' => 30458,
                'service_zipcode' => '',
                'phone' => '',
                'fax' => '',
                'email' => '',
                'facebook' => '',
                'twitter' => '',
                'linkedin' => '',
                'gplus' => '',
                'latitude' => '',
                'longitude' => '',
                'url' => '',
                'created_at' => '2019-04-22 07:15:43',
                'updated_at' => '2019-04-22 07:18:11',
            )

    );
$hierarchy = [];
if (! empty($locations)) {
 foreach ($locations as $location) {
  $hierarchy[$location['country']][$location['state']] = $location;
 }
}

if (! empty($hierarchy)) {
 foreach ($hierarchy as $country => $location) {
  echo "<br/>" . $country;
  if (! empty($hierarchy[$country])) {
   foreach ($hierarchy[$country] as $state => $city) {
    echo "<br/>--> " . $state;
    echo "<br/>----> " . $city['city'];
   }
  }
 }
}

Output:

USA
--> Georgia
----> Savannah
--> Georigia
----> Augusta

Where `USA` -> Country Name
Starting with `-->`: state name
Starting with `---->`: city name

Live Demo: