Reputation: 54949
I am trying to Compare and merge arrays in php. Lets say i have two arrays as follows
$topCountries1 = array(
array(
'India',
'23',
'34',
'11'),
array(
'USA',
'13',
'24',
'21'),
array(
'Japan',
'13',
'24',
'21'));
$topCountries2 = array(
array(
'France',
'23',
'34',
'11'),
array(
'India',
'13',
'24',
'21'),
array(
'Japan',
'13',
'24',
'21'));
I want to merge the above two arrays so that i will have unique set of values for the countries and if there are duplicate countries in the array it should add the values of the other three fields and combine it.
Trying out the following code - but i am confused with the logic.
$topCountries = array_merge($topCountries1, $topCountries2);
$collect = array();
foreach ($topCountries as $tc) {
echo $count = count($collect);
if ($count > 0) {
foreach ($collect as $c) {
if ($c[0] == $tc[0]) {
echo "match<br/>";
$collect[] = $tc;
} else {
$collect[] = $tc;
echo "no match<br/>";
}
}
} else {
$collect[] = $tc;
}
echo "<br/>";
}
Upvotes: 1
Views: 1130
Reputation: 52802
You can do it by simply keeping a global array organized by the key you want to merge, and you'll avoid having to do it with O(n²) complexity, just simple O(n) assuming that the hash lookup for the key is O(1).
This is a simpler solution than the one previously posted and accepts an arbitrary number of input arrays without having to add more code, in addition to allowing you to expand the number of values after the country name without having to add more code.
$topCountries1 = array(
array(
'India',
'23',
'34',
'11',
),
array(
'USA',
'13',
'24',
'21',
),
array(
'Japan',
'13',
'24',
'21',
),
);
$topCountries2 = array(
array(
'France',
'23',
'34',
'11',
),
array(
'India',
'13',
'24',
'21',
),
array(
'Japan',
'13',
'24',
'21',
),
);
$countries = array();
$data = array($topCountries1, $topCountries2);
foreach($data as $entries)
{
foreach($entries as $country)
{
$name = $country[0];
// if first time we see the country, add it to the list
if (!isset($countries[$name]))
{
$countries[$name] = $country;
}
else
{
// add all fields after the first (the name)
foreach (array_slice($country, 1, null, true) as $idx => $value)
{
$countries[$name][$idx] += $value;
}
}
}
}
var_dump($countries);
var_dump(array_values($countries));
Hope that helps!
Upvotes: 2
Reputation: 4631
I tried your answer in different way, and resulted what you want.
$topCountries1 = array(
array(
'India',
'23',
'34',
'11'),
array(
'USA',
'13',
'24',
'21'),
array(
'Japan',
'13',
'24',
'21'));
$topCountries2 = array(
array(
'France',
'23',
'34',
'11'),
array(
'India',
'13',
'24',
'21'),
array(
'Japan',
'13',
'24',
'21'));
$collection = array();
foreach ($topCountries1 as $tc1) {
foreach($topCountries2 as $tc2){
if(in_array($tc1[0], $tc2)){
$collect[0] = $tc1[0];
$collect[1] = $tc1[1] + $tc2[1];
$collect[2] = $tc1[2] + $tc2[2];
$collect[3] = $tc1[3] + $tc2[3];
array_push($collection, $collect);
}
}
}
$final_array = $collection;
foreach($topCountries1 as $tc1){
$flag = true;
foreach($collection as $coll){
if(in_array($tc1[0], $coll)){
$flag = false;
break;
}
}
if($flag){
array_push($final_array, $tc1);
}
}
foreach($topCountries2 as $tc1){
$flag = true;
foreach($collection as $coll){
if(in_array($tc1[0], $coll)){
$flag = false;
break;
}
}
if($flag){
array_push($final_array, $tc1);
}
}
var_dump($final_array);
array_merge will merge data it want add data
Upvotes: 2