Jeff
Jeff

Reputation: 6130

How to merge arrays and add an empty element if key doesn't exist

I have these 3 arrays:

$a1 = array( 'a' => 1, 'b' => 2, 'c' => 3 );
$a2 = array( 'a' => 4, 'b' => 5, 'd' => 6 );
$a3 = array( 'a' => 7, 'c' => 8, 'd' => 9, 'x' => 10 );

I want to merge them so the result looks like this:

Array(
[a] => Array(
        [0] => 1
        [1] => 4
        [2] => 7
    )
[b] => Array(
        [0] => 2
        [1] => 5
        [2] => 
    )
[c] => Array(
        [0] => 3
        [1] => 
        [2] => 8
    )
[d] => Array(
        [0] => 
        [1] => 6
        [2] => 9
    )
[x] => Array(
        [0] => 
        [1] => 
        [2] => 10
    )

... and I will be using the data in a simple table like this:

  col-1 col-2  col-3
a   1     4      7
b   2     5      -
c   3     -      8
d   -     6      9
x   -     -     10

array_merge_recursive is close, but doesn't give me the empty elements, so I believe I need a loop to get the job done. My problem is figuring out which function I need to use in that loop.

I'd be happy just to merge 2 arrays at a time with a custom user function.

Upvotes: 1

Views: 3012

Answers (6)

BIT CHEETAH
BIT CHEETAH

Reputation: 1200

→ Had already started on this before there where any answers, decided to finish it even though there are already acceptable answers. This version is more dynamic though and has some customization for the table's styling:

CODE:

/* Arrays from Question */  $a1 = array( 'a' => 1, 'b' => 2, 'c' => 3 ); $a2 = array( 'a' => 4, 'b' => 5, 'd' => 6 ); $a3 = array( 'a' => 7, 'c' => 8, 'd' => 9, 'x' => 10 );
/* Process Arrays       */  $result = handle_arrays( $a1, $a2, $a3 );
/* Create & Echo Table  */  echo ( array_table( $result ) );

function handle_arrays() {
    /* Get Arrays    */  $params = func_get_args(); $result = array();
    /* Merge Arrays  */  foreach( $params as $k=>$v ) { foreach( $v as $key=>$val ) { if( !array_key_exists( $key, $result ) ) $result[ $key ] = array(); $result[ $key ][ $k ] = $val; } }
    /* Handle Blanks */  for( $x = 0; $x < func_num_args(); $x++ ) { foreach( $result as $key=>$val ) { if( !array_key_exists( $x, $val ) ) { $result[ $key ][ $x ] = '-'; } ksort( $result[ $key ] ); } }
    /* Return Array  */  $return = array( func_num_args(), $result );
    return( $return );
}
function array_table( $array ) {
    /* Array # & Result Array */  $n = $array[ 0 ]; $a = $array[ 1 ];
    /* Style & Class Control  */  $padding_left = 10; $padding_right = 10; $col_align = "center"; $key_align = "left"; $table_class = ""; $col_class = ""; $row_class = ""; $field_class = "";
    /* Table & Column Headers */  $html = "<table class='{$table_class}'><tr><td style='padding-right:{$padding_right}px'></td>"; for( $x=0; $x<$n; $x++ ) { $html .= "<td style='padding-left:{$padding_left}px;padding-right:{$padding_right}px' class='{$col_class}'>col-$x</td>"; } $html .= "</tr>";
    /* Row and Fields Values  */  foreach( $a as $key=>$val ) { $html .= "<tr><td align='{$key_align}' class='{$row_class}'>$key</td>"; foreach( $val as $k=>$v ) { $html .= "<td align='{$col_align}' class='{$field_class}'>$v</td>"; } $html .= "</tr>"; } $html .= "</table>";
    return( $html );
}

OUTPUT:

    col-0   col-1   col-2
a     1       4       7
b     2       5       -
c     3       -       8
d     -       6       9
x     -       -       10

Upvotes: 1

alwaysLearn
alwaysLearn

Reputation: 6950

try this

<?php
 $a1 = array( 'a' => 1, 'b' => 2, 'c' => 3 );
 $a2 = array( 'a' => 4, 'b' => 5, 'd' => 6 );
$a3 = array( 'a' => 7, 'c' => 8, 'd' => 9, 'x' => 10 );
  function merge_common_keys(){
$arr = func_get_args();
$num = func_num_args();

$keys = array();
$i = 0;
for($i=0;$i<$num;++$i){
    $keys = array_merge($keys, array_keys($arr[$i]));
}
$keys = array_unique($keys);

$merged = array();

foreach($keys as $key){
    $merged[$key] = array();
    for($i=0;$i<$num;++$i){
        $merged[$key][] = isset($arr[$i][$key])?$arr[$i][$key]:null;
    }
}
  return $merged;
  }

$merged = merge_common_keys($a1,$a2,$a3);

print_r($merged);



$table = "<table>";




$table .= "<tr><td></td><td>col1</td><td>col2</td><td>col3</td></tr>";

foreach($merged as  $key=>$value)
  {
    $row = "<tr><td>$key</td>";
     foreach($value as $subvalue)
 {
   $row .= "<td>$subvalue</td>"; 
 }
 $table .= $row;
}
$table .= "</table>";
echo $table;
?>

ref : PHP, Merging arrays with common keys

see live demo http://codepad.viper-7.com/v8Ol5H

Upvotes: 3

Prasanth Bendra
Prasanth Bendra

Reputation: 32780

Try this :

<?php
$a1    = array( 'a' => 1, 'b' => 2, 'c' => 3 );
$a2    = array( 'a' => 4, 'b' => 5, 'd' => 6 );
$a3    = array( 'a' => 7, 'c' => 8, 'd' => 9, 'x' => 10 );

$arr   = array($a1,$a2,$a3);
$cnt   = count($arr);

$res   = array();
foreach($arr as $key=>$val){
   foreach($val as $k=>$v){
     $res[$k][$key]  = $v;
   }
}
echo "<table>";
echo "<tr><td>&nbsp;</td><td>col-1</td><td>col-2</td><td>col-3</td></tr>";
foreach($res as $ky=>$vl){
   echo "<tr>";
   echo "<td>".$ky."</td>";
   for($i=0;$i<$cnt;$i++){
      if(array_key_exists($i,$vl)){
         echo "<td>".$vl[$i]."</td>";
      }
      else{
         echo "<td> - </td>";
      }
   }
   echo "</tr>";
}
echo "</table>";
?>

output :

    col-1   col-2   col-3
a   1       4       7
b   2       5       -
c   3       -       8
d   -       6       9
x   -       -       10

Upvotes: 4

DaveRandom
DaveRandom

Reputation: 88697

I think the simplest approach to this would be obtain a list of all keys from all input arrays, then iterate the list of keys to construct the result array:

$keys = array_unique(
    array_merge(
        array_keys($a1),
        array_keys($a2),
        array_keys($a3)
    )
);

$result = array();
foreach ($keys as $key) {
    $result[$key] = array(
        isset($a1[$key]) ? $a1[$key] : null,
        isset($a2[$key]) ? $a2[$key] : null,
        isset($a3[$key]) ? $a3[$key] : null
    );
}

print_r($result);

See it working

...or if you want to supply an array of arrays with an arbitrary number of input arrays:

$keys = array();
foreach ($arrs as $arr) {
    $keys = array_merge($keys, array_keys($arr));
}
$keys = array_unique($keys);

$result = array();
foreach ($keys as $key) {
    $result[$key] = array();
    foreach ($arrs as $arr) {
        $result[$key][] = isset($arr[$key]) ? $arr[$key] : null;
    }
}

print_r($result);

See it working

Upvotes: 5

Mihai Matei
Mihai Matei

Reputation: 24276

function myMergeFunction() {

  $my_new_array = array();

  $arg_list = func_get_args();
  for ($i = 0; $i < count($arg_list); $i++) {

    foreach($arg_list[$i] as $key => $value) {
      if(!is_array($my_new_array[$key]))
        $my_new_array[$key] = array();

      $my_new_array[$key][] = $value

    }

  }

  return $my_new_array;

}

you can call it like:

myMergeFunction($a, $b, $c, $d, [...]);

Upvotes: 1

Timmetje
Timmetje

Reputation: 7694

You need to create something similar like array_merge_recursive().

But there might be a simpler solution, you say:

but doesn't give me the empty elements,

But you do know they don't exist!

So if you know the maximum amount of columns (amount of arrays) you need and you loop then you can always do:

if(isset($row[$column])) {
   echo $row[$column];//your column
} else {
   echo 0;
}

Upvotes: 1

Related Questions