【问题标题】:Combine two arrays, adding up overlapping results合并两个数组,将重叠的结果相加
【发布时间】:2011-07-05 18:06:04
【问题描述】:

我正在尝试合并两个具有一些重叠结果和一些不同结果的数组,如下所示:

array(
 [0] => array('name' => 'John', 'score' => '9');
 [1] => array('name' => 'Pete', 'score' => '2');
 [2] => array('name' => 'Eric', 'score' => '7');
)

array(
 [0] => array('name' => 'Lisa', 'score' => '1');
 [1] => array('name' => 'Pete', 'score' => '5');
 [2] => array('name' => 'Mary', 'score' => '4');
)

这应该会产生一个包含五个(而不是六个)结果的数组。皮特的分数应该是他的两个分数的总和,即'7'。

是否有一个简单的功能,或者我必须foreach一个(或两个?)列表并相互检查它们?我不知道如何开始,如果指向正确的方向,将不胜感激!

编辑:

所以.. 实际上两个数组都填充了对象.. 有什么新想法吗?

【问题讨论】:

  • 在合并部分使用合并排序并检查与先前元素的相等性

标签: php arrays merge


【解决方案1】:

这样就可以了

$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);

【讨论】:

  • 投反对票的原因:格式错误、答案不完整(他要求合并)和性能不是最佳
  • @Chimoo:我的电脑挂了,我的编辑(但未完成)的帖子已提交,请再等一分钟,我的帖子将准备就绪
  • 由于某种原因,在 foreach 中 $array1 和 $array2 实际上变成了对象..?
  • 不得不对整个事情进行一点修改 - 现在这适用于所有情况
【解决方案2】:

由于不同,此任务没有功能。使用这个算法:

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;
}

对不起,我的英语不好。 祝你好运!

【讨论】:

  • 感谢您的回答!我不认为它完全符合我的要求,因为它似乎没有添加分数?无论如何,我知道如何做到这一点,这就是我所需要的。
【解决方案3】:

如果你稍微重新设计你的数组如下:

希望对你有帮助

<?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);


?>

你也可以在这里查看结果:http://codepad.org/9hKF8oVC

【讨论】:

  • 重新设计让它变得琐碎。也许这不是他想要的
  • 是的,你说得对,我同意,但这只会让他的事情变得容易,不需要去 foreach 两次.....
【解决方案4】:
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;
}

未经测试,它应该适用于任意数组编号

【讨论】:

    【解决方案5】:

    创建一个临时查找数组并从中重新创建最终数组。这是一个使用额外空间的 O(n) 算法。在此处查看: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);
    
    ?>
    

    【讨论】:

    • 这个问题和 Thariama 的回答有同样的问题。它将数组转换为 foreach 中的对象
    • @stephan 感谢您指出这一点。我们也可以使用 for 循环遍历它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多