0

I have tried a number of PHP functions like array_unique to merge the arrays I have but that does not work since these are not strings.

The starting output would be this on var_dump( $country_cities );

array (size=3)
  0 => 
    array (size=1)
      'BH' => 
        array (size=4)
          'post_id' => int 7886
          'country' => string 'BH' (length=2)
          'city_name_eng' => string 'Laurence' (length=8)
          'city_name_arabic' => string '3684hdfpfwbhisf' (length=15)
  1 => 
    array (size=1)
      'BH' => 
        array (size=4)
          'post_id' => int 7885
          'country' => string 'BH' (length=2)
          'city_name_eng' => string 'Bahrain City' (length=12)
          'city_name_arabic' => string 'vgdg824762' (length=10)
  2 => 
    array (size=2)
      'BH' => 
        array (size=4)
          'post_id' => int 7885
          'country' => string 'BH' (length=2)
          'city_name_eng' => string 'Bahrain City' (length=12)
          'city_name_arabic' => string 'vgdg824762' (length=10)
      'KW' => 
        array (size=4)
          'post_id' => int 7841
          'country' => string 'KW' (length=2)
          'city_name_eng' => string 'Kuwait City' (length=11)
          'city_name_arabic' => string ' مدينة الكويت' (length=24)

The Code below merges the different arrays above.

<?php

    // Make the cities unique. Remove duplicates form the inner array.
    $uniques = [];

    foreach($country_cities as $arr ) {
        foreach( $arr as $v) {
            if( !in_array($v, $uniques, false) ) {
                $uniques[$v['country']] = $v;
            }
        }
    }

var_dump($uniques);

Results logged show the code cuts out some of the arrays.

/Users/..... on line php:74:

array (size=2)
  'BH' => 
    array (size=4)
      'post_id' => int 7885
      'country' => string 'BH' (length=2)
      'city_name_eng' => string 'Bahrain City' (length=12)
      'city_name_arabic' => string 'vgdg824762' (length=10)
  'KW' => 
    array (size=4)
      'post_id' => int 7841
      'country' => string 'KW' (length=2)
      'city_name_eng' => string 'Kuwait City' (length=11)
      'city_name_arabic' => string ' مدينة الكويت' (length=24)

Please help figure out my error or suggest a better way to fix it.

6
  • I think it would be helpful for people to have a starting point array(s) with data or intermediary result arrays. Commented Jan 3, 2021 at 11:08
  • 1
    Why is Laurence not in the output array? Commented Jan 3, 2021 at 11:19
  • What kind of items would you like to make unique? Country|City|Post? Commented Jan 3, 2021 at 12:50
  • @dekameron I want to have the last dump of data at the bottom steming from the first dump. Commented Jan 3, 2021 at 14:23
  • @omukiguy Do the city arrays get grouped under the country code? Such that 'BH' is an array of arrays? Could you provide an example result set you want to achieve? Have you already checked the provided answer? Commented Jan 3, 2021 at 14:32

2 Answers 2

1

If I understood you correctly, this should be the result you wanted to achieve. Each country code will be included once, while the cities (based on post_id) will only be added once.

<?php

$result = [];
$processedIds = [];

foreach ($country_cities as $ccs) {
    foreach ($ccs as $cc => $details) {
        // If the country has not yet been added to
        // the result we create an outer array.
        if (!key_exists($cc, $result)) {
            $result[$cc] = [];
        }

        $postId = $details['post_id'];
        if (!in_array($postId, $processedIds)) {
            // Add the unique city to country's collection
            $result[$cc][] = $details;

            // Keep track of the post_id key.
            $processedIds[] = $postId;
        }
    }
}

print_r($result);
Sign up to request clarification or add additional context in comments.

1 Comment

Asante sana (Swahili for thank you very much). It is perfect.
1
<?php

//...
$uniques = [];

    foreach($country_cities as $data ) {
        foreach( $data as $countryCode => $item) {
            if( !array_key_exists($countryCode, $uniques) ) {
                $uniques[$countryCode] = []; //Create an empty array 
            }
            $targetArray = &$uniques[$countryCode];
            if( !array_key_exists($item['post_id'], $targetArray) ) {
                $targetArray[$item['post_id']] = $item; //Create an empty array 
            }
        }
    }

Maybe this code will help?

5 Comments

This is getting to what I need. However, It adds a level deep. How do I remove ` $targetArray[$item['post_id']] ` and still have the other items appear nested one level above what is in the code above.
I just need the e.g 'KW'or 'BH' with direct arrays of the items under it. like in the bottom dump
@omukiguy I think it's best to accept this answer unless you really have different expectations of how the result set should look like and if you can provide a concise example of it.
@remy The answer you presented was exactly what I needed though you deleted it. I think this answer will give researchers more options in the future.
@omukiguy Alright I'm sorry although in my honest opinion it does not differ from the earlier presented answer. Except for minor differences. (I undeleted it again)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.