php - How comes 2 in my multidimensional array merge?
Get the solution ↓↓↓I'm trying to merge the duplicate values of a key in mutlidimensional array.
$subjects = array(
array(
'class' => 'one',
'sub' => 'music',
),
array(
'class' => 'one',
'sub' => array( 'social', 'health', 'science' ),
),
array(
'class' => 'two',
'sub' => 'music',
),
array(
'class' => 'one',
'sub' => 'math',
)
);
In the above, I'll need to find the common class and merge their sub into an array. So, the expected output is like:
{-code-2}
I'm trying to acheive that result, but I'm getting2
out of nowhere.
$class_sub = array();
$result = array();
foreach( $subjects as $sub ) {
if ( ! isset( $class_sub[ $sub['class'] ] ) ) {
$class_sub[ $sub['class'] ] = $sub['sub'];
} else {
if ( is_array( $class_sub[ $sub['class'] ] ) ) {
$new = array_push( $class_sub[ $sub['class'] ], $sub['sub'] );
} else {
$new[] = $sub['sub'];
}
$class_sub[ $sub['class'] ] = $new;
}
}
foreach( $class_sub as $class => $sub ) {
$result[] = array(
'class' => $class,
'sub' => $sub
);
}
echo "<pre>"; print_r( $result ); echo "</pre>";
Here I'm getting2
as sub:
Array
(
[0] => Array
(
[class] => one
[sub] => 2
)
[1] => Array
(
[class] => two
[sub] => music
)
)
How comes2
and how do I achevive the desired result instead? Thank you.
Answer
Solution:
returns the number of elements in the new array, not the changed array, which is why you are getting
2
in your output. That is not your only issue though as you need to take into account the fact that$sub
can also be an array, in which case usingarray_push
will give you an array of arrays in the output. Instead, use :
if ( is_array( $class_sub[ $sub['class'] ] ) ) {
$new = array_merge( $class_sub[ $sub['class'] ], is_array($sub['sub']) ? $sub['sub'] : array($sub['sub']));
} else {
$new = array_merge( array($class_sub[ $sub['class'] ]), is_array($sub['sub']) ? $sub['sub'] : array($sub['sub']));
}
Output for your sample data:
Array
(
[0] => Array
(
[class] => one
[sub] => Array
(
[0] => music
[1] => social
[2] => health
[3] => science
[4] => math
)
)
[1] => Array
(
[class] => two
[sub] => music
)
)
Answer
Solution:
Out of curiosity I wrote my own version of your function. So, this is not a direct answer to your question but, maybe, still of interest to someone else here who is trying to "merge" an array in the way you specified it.
function amerge($arr){
foreach ($arr as $e){
$sub=is_array($e["sub"])?$e["sub"]:array($e["sub"]);
foreach ($sub as $s) $p[$e["class"]][$s]=1;
}
$classes=array_keys($p);
foreach ($classes as $c)
$out[]=array("class"=>$c,"sub"=>array_keys($p[$c]));
return $out;
}
For a demo click here: https://rextester.com/QKULS37967
Answer
Solution:
The problem is that you are using incorrectly. The function returns the number of elements in the array, not the array itself - the items get added to the array in the first parameter, i.e.
$class_sub[ $sub['class'] ]
You have this in your code:
if ( is_array( $class_sub[ $sub['class'] ] ) ) {
$new = array_push( $class_sub[ $sub['class'] ], $sub['sub'] );
} else {
$new[] = $sub['sub'];
}
$class_sub[ $sub['class'] ] = $new;
What's happening here is that the arrays are getting added together, and then the count of the array items ($new
) is added to$class_sub[ $sub['class'] ]
.
Try this instead - this will not overwrite$class_sub[ $sub['class'] ]
and it uses array_merge to add the arrays together (this replaces the wholeforeach( $subjects as $sub )
block, not just the code above):
foreach( $subjects as $sub ) {
/* prepare subjects as an array */
if ( is_array( $sub['sub'] ) ) $subjects = $sub['sub'];
else $subjects = array($sub['sub']);
if ( ! isset( $class_sub[ $sub['class'] ] ) )
/* if this is the first subject for this class, there is no array to merge with */
$class_sub[ $sub['class'] ] = $subjects;
else
/* We know both class and subject are arrays so we can merge them */
$class_sub[$sub['class']] = array_merge( $class_sub[ $sub['class'] ], $subjects);
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: to enable extensions, verify that they are enabled in your .ini files
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.