Combine two arrays, adding up overlapping results
I'm trying to merge two arrays that have some overlapping results and some that are different, like this:
array(
[0] => array('name' => 'John', 'score' =开发者_StackOverflow社区> '9');
[1] => array('name' => 'Pete', 'score' => '2');
[2] => array('name' => 'Eric', 'score' => '7');
)
and
array(
[0] => array('name' => 'Lisa', 'score' => '1');
[1] => array('name' => 'Pete', 'score' => '5');
[2] => array('name' => 'Mary', 'score' => '4');
)
This should result in one array of five (not six) results. The score for Pete should be the sum of his two scores, i.e. '7'.
Is there an easy function for this, or do I have to foreach one (or both?) lists and check them against eachother? I'm not sure how to get started on this, a pointer in the right direction would be appreciated!
edit:
So.. actually both arrays are populated with objects.. Any new ideas?
Create a temporary lookup array and recreate your final array from it. This is a O(n) algorithm using extra space.See it here : http://codepad.org/4aL5KMR4
<?php
$arr1 =
array(
array('name' => 'John', 'score' => '9'),
array('name' => 'Pete', 'score' => '2'),
array('name' => 'Eric', 'score' => '7'),
);
$arr2=
array(
array('name' => 'Lisa', 'score' => '1'),
array('name' => 'Pete', 'score' => '5'),
array('name' => 'Mary', 'score' => '4'),
);
$res = array();
$revLookUp = array();
foreach($arr2 as $row)
{
if(isset($revLookUp[$row['name']]) == true)
$revLookUp[$row['name']] += $row['score'];
else
$revLookUp[$row['name']] = $row['score'];
}
foreach($arr1 as $row)
{
if(isset($revLookUp[$row['name']]) == true)
$revLookUp[$row['name']] += $row['score'];
else
$revLookUp[$row['name']] = $row['score'];
}
foreach($revLookUp as $key => $value){
$res[] = array('name' => $key, 'score' => $value);
}
print_r($res);
?>
There are no function for this task due to differents. Use this algorithm:
function merge($array1, $array2)
{
$result = array();
$count = (count($array1) > count($array2)) ? count($array1) : count($array2);
for($i=0; $i<$count; $i++)
{
if($array1[$i]['name'] != $array2[$i]['name'])
{
$result[] = $array1[$i];
$result[] = $array2[$i];
}
else
{
$array1['score'] += $array2['score'];
$result[] = $array1[$i];
}
}
return $result;
}
Sorry for my bad english. Good luck!
function vector_sum($a, $b) {
$arrays=func_get_args();
$res=array(); $result=array();
foreach($arrays as $current) {
$res=array_reduce($current, function($res, cur){
@$res[$cur['name']]+=$cur['score'];
return $res;
}, $res);
}
// sums done. put the result array in shape
foreach ($res ad $name=>$score)
array_push($result, array('name'=>$name, 'score'=>$score));
}
return $result;
}
Not tested, it should works with an arbitrary arrays number
This will do the job
$array1 = array(
array('name' => 'John', 'score' => 9),
array('name' => 'Pete', 'score' => 2),
array('name' => 'Eric', 'score' => 7),
);
$array2 = array(
array('name' => 'Lisa', 'score' => 1),
array('name' => 'Pete', 'score' => 5),
array('name' => 'Mary', 'score' => 4),
);
$result = array();
$names = array();
foreach ($array2 as $elem2){
$cc = 0;
foreach ($array1 as $key => $elem1){
$cc++;
if ($elem1['name'] == $elem2['name']) {
$names[$elem1['name']] = $elem1['score'] + $elem2['score'];
break;
}
else if ($cc == count($array1)) {
array_push ($result, $elem2);
}
}
}
foreach ($array1 as $elem1){
if ($names[$elem1['name']]){
$elem1['score'] = $names[$elem1['name']];
}
array_push ($result, $elem1);
}
print_r($result);
if you slightly re design you array as follows:
hope it helps
<?php
$a = array(
'John' => '9',
'Pete' => '2',
'Eric' => '7',
);
$b = array(
'Lisa' => '1',
'Pete' => '5',
'Mary' => '4',
);
$newArray = $a;
foreach($b as $key => $value) {
if(array_key_exists($key, $newArray)){
$newArray[$key] += $value;
}else{
$newArray[$key] = $value;
}
}
print_r($newArray);
?>
also you can view the result here: http://codepad.org/9hKF8oVC
精彩评论