skip to Main Content

I have the following scenario made of arrays with numeric keys.
I need to have an array which stores all the values in the arrays grouped by numeric key and without duplicates.
I cannot make them strings as they are IDs and need to stay numeric.

Starting point:

    Array
    (
        [77] => Array
            (
                [0] => Bold Condensed
                [1] => Bold Condensed 2
                [2] => Bold Condensed 3
            )
    
    )
    Array
    (
        [77] => Array
            (
                [0] => Bold Condensed
            )
    
        [136] => Array
            (
                [0] => Regular
            )
    
    )
    Array
    (
        [77] => Array
            (
                [0] => Bold Condensed (1, 2, 3)
            )
    
        [168] => Array
            (
                [0] => Regular
                [1] => Bold
            )
    
    )

Expected output:

Array
(
    [77] => Array
        (
            [0] => Bold Condensed
            [1] => Bold Condensed 2
            [2] => Bold Condensed 3
            [3] => Bold Condensed (1 ,2 ,3)
        )

    [136] => Array
        (
            [0] => Regular
        )

    [168] => Array
        (
            [0] => Regular
            [1] => Bold
        )

)

Tried array_merge and array_merge_recursive:

$megaArray = [];

foreach( $arrays as $key => $value) {
  if(array_key_exists($key, $arrays)){
    $megaArray[$key] = array_merge_recursive($value);
  }
}

What I’m getting with both array_merge and array_merge_recursive:

Array
(
    [77] => Array
        (
            [0] => Bold Condensed (1, 2, 3)
        )

    [136] => Array
        (
            [0] => Regular
        )

    [168] => Array
        (
            [0] => Regular
            [1] => Bold
        )

)

Both array_merge and array_merge_recursive seem to store the latest value for each key.

5

Answers


  1. I think you just need a combination of array_merge and array_unique (since I note you don’t have duplicates in your leaf arrays):

    $megaArray = [];
    
    foreach ($arrays as $subArray) {
      foreach ($subArray as $key => $value) {
        if (array_key_exists($key, $megaArray)) {
          $megaArray[$key] = array_unique(array_merge($megaArray[$key], $value));
        } else {
          $megaArray[$key] = $value;
        }
      }
    }
    
    Login or Signup to reply.
  2. Based on your expected output, it seems you need to check key and values at the same time. I write a code that create exact output array like your sample. No need to say that you can use function to simplify the whole process but for understanding the principle of situation, I repeat foreach each time.

    $newarray = array();
    
    //-------------
    $array1 = array();
    $array1[77][0] = 'Bold Condensed';
    $array1[77][1] = 'Bold Condensed 2';
    $array1[77][2] = 'Bold Condensed 3';
    
    foreach($array1 as $key => $value) {
        if (array_key_exists($key, $newarray)) {
            foreach($value as $subkey => $subvalue) {
                if (!array_key_exists($subkey, $newarray[$key])) {
                    $newarray[$key][$subkey] = $subvalue;
                } else if (array_key_exists($subkey, $newarray[$key]) and $subvalue != $newarray[$key][$subkey]) {
                    $newkey = count($newarray[$key]);
                    $newarray[$key][$newkey] = $subvalue;
                }
            }
        } else {
            $newarray[$key] = $value;
        }
    }
    
    //-------------
    $array2 = array();
    $array2[77][0] = 'Bold Condensed';
    $array2[136][0] = 'Regular';
    
    foreach($array2 as $key => $value) {
        if (array_key_exists($key, $newarray)) {
            foreach($value as $subkey => $subvalue) {
                if (!array_key_exists($subkey, $newarray[$key])) {
                    $newarray[$key][$subkey] = $subvalue;
                } else if (array_key_exists($subkey, $newarray[$key]) and $subvalue != $newarray[$key][$subkey]) {
                    $newkey = count($newarray[$key]);
                    $newarray[$key][$newkey] = $subvalue;
                }
            }
        } else {
            $newarray[$key] = $value;
        }
    }
    
    //-------------
    $array3 = array();
    $array3[77][0] = 'Bold Condensed (1, 2, 3)';
    $array3[168][0] = 'Regular';
    $array3[168][1] = 'Bold';
    
    foreach($array3 as $key => $value) {
        if (array_key_exists($key, $newarray)) {
            foreach($value as $subkey => $subvalue) {
                if (!array_key_exists($subkey, $newarray[$key])) {
                    $newarray[$key][$subkey] = $subvalue;
                } else if (array_key_exists($subkey, $newarray[$key]) and $subvalue != $newarray[$key][$subkey]) {
                    $newkey = count($newarray[$key]);
                    $newarray[$key][$newkey] = $subvalue;
                }
            }
        } else {
            $newarray[$key] = $value;
        }
    }
    
    //Final result
    print('<pre>'.print_r($newarray, true).'</pre>');
    
    Login or Signup to reply.
  3. array_merge_recursive is not required since there is only 1 level for each ID and your array_key_exists will always be true since you are getting the same key from foreach and checking on the same array.


    You can straightaway get values based on id (which is 77 etc in your case) and keep merging values. You can later array_unique them only once for efficiency and get only unique values for each id.

    <?php
    
    $result = [];
    
    foreach($d as $subs){
        foreach($subs as $id => $values){
            $result[ $id ] = array_merge($result[ $id ] ?? [], $values);
        }
    }
    
    $result = array_map(fn($v) => array_unique($v), $result);
    
    print_r($result);
    

    Live Demo

    Login or Signup to reply.
  4. foreach ($arrays as $array) {
      foreach ($array as $key => $values) {
        $result[$key] = array_unique(array_merge($result[$key] ?? [], ...[ $values ]));
      }
    }
    
    Login or Signup to reply.
  5. here is the code

      <?php
        
        
        // Given arrays
        $array1 = [
            77 => ['Bold Condensed', 'Bold Condensed 2', 'Bold Condensed 3'],
        ];
        
        $array2 = [
            77 => ['Bold Condensed'],
            136 => ['Regular'],
        ];
        
        $array3 = [
            77 => ['Bold Condensed (1, 2, 3)'],
            168 => ['Regular', 'Bold'],
        ];
        
        // Function to merge arrays
        function mergeArrays(...$arrays)
        {
            $result = [];
        
            foreach ($arrays as $array) {
                foreach ($array as $key => $values) {
                    if (!isset($result[$key])) {
                        $result[$key] = $values;
                    } else {
                        // Merge values, removing duplicates
                        $result[$key] = array_values(array_unique(array_merge($result[$key], $values)));
                    }
                }
            }
        
            return $result;
        }
        
        // Merge the arrays
        $mergedArray = mergeArrays($array1, $array2, $array3);
        
        // Output the merged array
        print_r($mergedArray);
        
        ?>
    

    The mergeArrays function will accepts multiple arrays as arguments and merges them into a single result array. It loop through each array, combining values for each key while removing duplicates

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search