Reputation: 6130
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
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
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
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> </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
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);
...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);
Upvotes: 5
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
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