Array merge recursive

There are a lot of examples here for recursion that are meant to behave more like array_merge() but they don't get it quite right or are fairly customised. I think this version is most similar, takes more than 2 arguments and can be renamed in one place:

<?php

function array_merge_recursive_simple() {

    if (func_num_args() < 2) {
       
trigger_error(__FUNCTION__ .' needs two or more array arguments', E_USER_WARNING);
        return;
    }
   
$arrays = func_get_args();
   
$merged = array();
    while (
$arrays) {
       
$array = array_shift($arrays);
        if (!
is_array($array)) {
           
trigger_error(__FUNCTION__ .' encountered a non array argument', E_USER_WARNING);
            return;
        }
        if (!
$array)
            continue;
        foreach (
$array as $key => $value)
            if (
is_string($key))
                if (
is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key]))
                   
$merged[$key] = call_user_func(__FUNCTION__, $merged[$key], $value);
                else
                   
$merged[$key] = $value;
            else
               
$merged[] = $value;
    }
    return
$merged;
}

$a1 = array(
   
88 => 1,
   
'foo' => 2,
   
'bar' => array(4),
   
'x' => 5,
   
'z' => array(
       
6,
       
'm' => 'hi',
    ),
);
$a2 = array(
   
99 => 7,
   
'foo' => array(8),
   
'bar' => 9,
   
'y' => 10,
   
'z' => array(
       
'm' => 'bye',
       
11,
    ),
);
$a3 = array(
   
'z' => array(
       
'm' => 'ciao',
    ),
);
var_dump(array_merge($a1, $a2, $a3));
var_dump(array_merge_recursive_simple($a1, $a2, $a3));
var_dump(array_merge_recursive($a1, $a2, $a3));
?>

gives:

array(7) {              array(7) {              array(7) {
  int(1)                  int(1)                  int(1)
  ["foo"]=>               ["foo"]=>               ["foo"]=>
  array(1) {              array(1) {              array(2) {
    [0]=>                   [0]=>                   [0]=>
    int(8)                  int(8)                  int(2)
  }                       }                         [1]=>
  ["bar"]=>               ["bar"]=>                 int(8)
  int(9)                  int(9)                  }
  ["x"]=>                 ["x"]=>                 ["bar"]=>
  int(5)                  int(5)                  array(2) {
  ["z"]=>                 ["z"]=>                   [0]=>
  array(1) {              array(3) {                int(4)
    ["m"]=>                 [0]=>                   [1]=>
    string(4) "ciao"        int(6)                  int(9)
  }                         ["m"]=>               }
  [1]=>                     string(4) "ciao"      ["x"]=>
  int(7)                    [1]=>                 int(5)
  ["y"]=>                   int(11)               ["z"]=>
  int(10)                 }                       array(3) {
}                         [1]=>                     [0]=>
                          int(7)                    int(6)
                          ["y"]=>                   ["m"]=>
                          int(10)                   array(3) {
                        }                             [0]=>
                                                      string(2) "hi"
                                                      [1]=>
                                                      string(3) "bye"
                                                      [2]=>
                                                      string(4) "ciao"
                                                    }
                                                    [1]=>
                                                    int(11)
                                                  }
                                                  [1]=>
                                                  int(7)
                                                  ["y"]=>
                                                  int(10)
                                                }

php.net

There are a lot of examples here for recursion that are meant to behave more like array_merge() but they don't get it quite right or are fairly customised. I think this version is most similar, takes more than 2 arguments and can be renamed in one place:

<?php

function array_merge_recursive_simple() {

    if (func_num_args() < 2) {
       
trigger_error(__FUNCTION__ .' needs two or more array arguments', E_USER_WARNING);
        return;
    }
   
$arrays = func_get_args();
   
$merged = array();
    while (
$arrays) {
       
$array = array_shift($arrays);
        if (!
is_array($array)) {
           
trigger_error(__FUNCTION__ .' encountered a non array argument', E_USER_WARNING);
            return;
        }
        if (!
$array)
            continue;
        foreach (
$array as $key => $value)
            if (
is_string($key))
                if (
is_array($value) && array_key_exists($key, $merged) && is_array($merged[$key]))
                   
$merged[$key] = call_user_func(__FUNCTION__, $merged[$key], $value);
                else
                   
$merged[$key] = $value;
            else
               
$merged[] = $value;
    }
    return
$merged;
}

$a1 = array(
   
88 => 1,
   
'foo' => 2,
   
'bar' => array(4),
   
'x' => 5,
   
'z' => array(
       
6,
       
'm' => 'hi',
    ),
);
$a2 = array(
   
99 => 7,
   
'foo' => array(8),
   
'bar' => 9,
   
'y' => 10,
   
'z' => array(
       
'm' => 'bye',
       
11,
    ),
);
$a3 = array(
   
'z' => array(
       
'm' => 'ciao',
    ),
);
var_dump(array_merge($a1, $a2, $a3));
var_dump(array_merge_recursive_simple($a1, $a2, $a3));
var_dump(array_merge_recursive($a1, $a2, $a3));
?>

gives:

array(7) {              array(7) {              array(7) {
  int(1)                  int(1)                  int(1)
  ["foo"]=>               ["foo"]=>               ["foo"]=>
  array(1) {              array(1) {              array(2) {
    [0]=>                   [0]=>                   [0]=>
    int(8)                  int(8)                  int(2)
  }                       }                         [1]=>
  ["bar"]=>               ["bar"]=>                 int(8)
  int(9)                  int(9)                  }
  ["x"]=>                 ["x"]=>                 ["bar"]=>
  int(5)                  int(5)                  array(2) {
  ["z"]=>                 ["z"]=>                   [0]=>
  array(1) {              array(3) {                int(4)
    ["m"]=>                 [0]=>                   [1]=>
    string(4) "ciao"        int(6)                  int(9)
  }                         ["m"]=>               }
  [1]=>                     string(4) "ciao"      ["x"]=>
  int(7)                    [1]=>                 int(5)
  ["y"]=>                   int(11)               ["z"]=>
  int(10)                 }                       array(3) {
}                         [1]=>                     [0]=>
                          int(7)                    int(6)
                          ["y"]=>                   ["m"]=>
                          int(10)                   array(3) {
                        }                             [0]=>
                                                      string(2) "hi"
                                                      [1]=>
                                                      string(3) "bye"
                                                      [2]=>
                                                      string(4) "ciao"
                                                    }
                                                    [1]=>
                                                    int(11)
                                                  }
                                                  [1]=>
                                                  int(7)
                                                  ["y"]=>
                                                  int(10)
                                                }

php.theraven7.com

Here's a function to recursively merge any number of any-dimensional arrays.
It actually works in quite a similar way as array_merge_recursive does, but with two major differences:
- Later elements overwrite previous ones having the same keys.
- Numeric keys are not appended. Instead, they are converted into associative ones, and therefore overwritten as stated above.

Usage:
   array array_merge_n(array array1, array array2[, array ...])

<?php
  
/**
     *  Merges two arrays of any dimension
     *
     *  This is the process' core!
     *  Here each array is merged with the current resulting one
     *
     *  @access private
     *  @author Chema Barcala Calveiro <shemari75@mixmail.com>
     *  @param array $array  Resulting array - passed by reference
     *  @param array $array_i Array to be merged - passed by reference
     */

   function array_merge_2(&$array, &$array_i) {
      
// For each element of the array (key => value):
      
foreach ($array_i as $k => $v) {
          
// If the value itself is an array, the process repeats recursively:
          
if (is_array($v)) {
               if (!isset(
$array[$k])) {
                  
$array[$k] = array();
               }
              
array_merge_2($array[$k], $v);

           // Else, the value is assigned to the current element of the resulting array:
          
} else {
               if (isset(
$array[$k]) && is_array($array[$k])) {
                  
$array[$k][0] = $v;
               } else {
                   if (isset(
$array) && !is_array($array)) {
                      
$temp = $array;
                      
$array = array();
                      
$array[0] = $temp;
                   }
                  
$array[$k] = $v;
               }
           }
       }
   }

   /**
     *  Merges any number of arrays of any dimension
     *
     *  The arrays to be merged are passed as arguments to the function,
     *  which uses an external function (array_merge_2) to merge each of them
     *  with the resulting one as it's being constructed
     *
     *  @access public
     *  @author Chema Barcala Calveiro <shemari75@mixmail.com>
     *  @return array Resulting array, once all have been merged
     */

   function array_merge_n() {
      
// Initialization of the resulting array:
      
$array = array();

       // Arrays to be merged (function's arguments):
      
$arrays =& func_get_args();

       // Merging of each array with the resulting one:
      
foreach ($arrays as $array_i) {
           if (
is_array($array_i)) {
              
array_merge_2($array, $array_i);
           }
       }

       return $array;
   }
?>

php.svchat.ru

Here's a function to recursively merge any number of any-dimensional arrays.
It actually works in quite a similar way as array_merge_recursive does, but with two major differences:
- Later elements overwrite previous ones having the same keys.
- Numeric keys are not appended. Instead, they are converted into associative ones, and therefore overwritten as stated above.

Usage:
    array array_merge_n(array array1, array array2[, array ...])

<?php
   
/**
     *  Merges two arrays of any dimension
     *
     *  This is the process' core!
     *  Here each array is merged with the current resulting one
     *
     *  @access private
     *  @author Chema Barcala Calveiro <shemari75@mixmail.com>
     *  @param array $array   Resulting array - passed by reference
     *  @param array $array_i Array to be merged - passed by reference
     */

    function array_merge_2(&$array, &$array_i) {
       
// For each element of the array (key => value):
       
foreach ($array_i as $k => $v) {
           
// If the value itself is an array, the process repeats recursively:
           
if (is_array($v)) {
                if (!isset(
$array[$k])) {
                   
$array[$k] = array();
                }
               
array_merge_2($array[$k], $v);

            // Else, the value is assigned to the current element of the resulting array:
           
} else {
                if (isset(
$array[$k]) && is_array($array[$k])) {
                   
$array[$k][0] = $v;
                } else {
                    if (isset(
$array) && !is_array($array)) {
                       
$temp = $array;
                       
$array = array();
                       
$array[0] = $temp;
                    }
                   
$array[$k] = $v;
                }
            }
        }
    }

    /**
     *  Merges any number of arrays of any dimension
     *
     *  The arrays to be merged are passed as arguments to the function,
     *  which uses an external function (array_merge_2) to merge each of them
     *  with the resulting one as it's being constructed
     *
     *  @access public
     *  @author Chema Barcala Calveiro <shemari75@mixmail.com>
     *  @return array Resulting array, once all have been merged
     */

    function array_merge_n() {
       
// Initialization of the resulting array:
       
$array = array();

        // Arrays to be merged (function's arguments):
       
$arrays =& func_get_args();

        // Merging of each array with the resulting one:
       
foreach ($arrays as $array_i) {
            if (
is_array($array_i)) {
               
array_merge_2($array, $array_i);
            }
        }

        return $array;
    }
?>

php.segmenta.ru

You May Also Like

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.