开发者

how to merge multidimensional arrays whilst preserving all unique key/values?

is there are in build php function or I have to write my own one to merge two multidimensional arrays like that

$list1 = array("school1" => array('string1','string2'));

$list2 = array("school1" => array('string1','string3'),
       开发者_开发技巧        "school2" => array('string1','string4','string5')
         );

into array where nothing will be overwritten or omitted. I want to have only unique values in the the 'second array'. Meaning that array school1 will contain string string1 once only

Array ( [school1] => Array ( [0] => string3 [1] => string2 [2] => string1 ) 
        [school2] => Array ( [0] => string5 [1] => string4 [2] => string1 ) ) 

ideal would be if I can have the second array = string1, string2 .... sorted desc


my solution

function merge_db_lists ($list1, $list2) {
  $final_array = array();
  $final_array = go_through_list($list1, $final_array);
  $final_array = go_through_list($list2, $final_array);
  return $final_array;
}   

function go_through_list($list,$output){
  foreach (array_keys($list) as $key){
    if (array_key_exists($key, $output)){
      foreach ($list[$key] as $item ){
        $output[$key][] = $item;
      }  
      arsort($output[$key]);
    }
    else{
      $output[$key] = $list[$key];
    }  
  }
  return $output;
}


I had a similar need because I needed to merge n-dimensional arrays containing configuration values, so I ended up writing a function, I just expanded it a bit to apply to n-dimensional arrays.

/**
 * Recursively merges $array2 to $array1 while keeping the $array2 values
 * and keys unique.
 *
 * @param array $array1 - destination array
 * @param array $array2 - array containing new values
 * @return array
*/
public function arraysMergeUnique($array1, $array2)
{
    foreach ($array2 as $k => $v)
    {
        if ( is_array($array1) )
        {
            // If the meaning the value is a string, and doesn't already exist, add it
            if ( is_string($v) && ! in_array($v, $array1) )
            {
                $array1[] = $v;
            }
            // If the value's an array, make a recursive call with it
            else if ( is_array($v) )
            {
                if ( isset($array1[$k]) )
                {
                    $array1[$k] = $this->arraysMergeUnique($array1[$k], $v);
                }
                else
                {
                    $array1[$k] = $v;
                }
            }                
        }
        else
        {
            $array1 = array($v);
        }
    }

    return $array1;
}

For example, if your list was even deeper, if 'school1' contained 'class1':

$list1 = array(
    'school1' => array(
        'string1',
        'string2',
        'class 1' => array(
            'student 1',
        )
    )
);

$list2 = array(
    'school1' => array(
        'string1',
        'string3',
        'class 1' => array(
            'student 1',
            'student 2',
        ),
        'class 2' => array(
            'student 3',
        ),
    ),
    'school2' => array(
        'string1', 
        'string4',
        'string5'
    )
);

the resulting array would merge it fully:

$result = array(
    'school1' => array(
        'string1',
        'string2',
        'class 1' => array(
            'student 1',
            'student 2'
        ),
        'string3',
        'class 2' => array(
            'student 3'
        )
    ),
    'school2' => array(
        'string1',
        'string4',
        'string5'
    )
);

The function should probably be written so that it works with references, and not values like this one, which would greatly improve performance with big arrays, but this one works just fine with smaller ones.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜