在PHP中以这种困难的方式合并2个数组

时间:2012-10-12 14:58:06

标签: php arrays

我有2个阵列 $ list $ list2

$列表

Array
(
[0] => Array
    (
        [team] => 14
        [team_points] => 3
        [team_occurrences] => 2
    )

[1] => Array
    (
        [team] => 1
        [team_points] => 3
        [team_occurrences] => 2
    )

[2] => Array
    (
        [team] => 5
        [team_points] => 1
        [team_occurrences] => 1
    )

[3] => Array
    (
        [team] => 13
        [team_points] => 1
        [team_occurrences] => 1
    )

[4] => Array
    (
        [team] => 7
        [team_points] => 0
        [team_occurrences] => 1
    )

[5] => Array
    (
        [team] => 2
        [team_points] => 0
        [team_occurrences] => 3
    )

 )

$ list2中:

Array
(
    [0] => Array
        (
            [team] => 20
            [team_points] => 7
            [team_occurrences] => 3
        )

    [1] => Array
        (
            [team] => 10
            [team_points] => 3
            [team_occurrences] => 1
        )

    [2] => Array
        (
            [team] => 14
            [team_points] => 3
            [team_occurrences] => 1
        )

    [3] => Array
        (
            [team] => 13
            [team_points] => 3
            [team_occurrences] => 1
        )

    [4] => Array
        (
            [team] => 19
            [team_points] => 3
            [team_occurrences] => 1
        )

    [5] => Array
        (
            [team] => 17
            [team_points] => 1
            [team_occurrences] => 1
        )

    [6] => Array
        (
            [team] => 11
            [team_points] => 0
            [team_occurrences] => 1
        )

    [7] => Array
        (
            [team] => 15
            [team_points] => 0
            [team_occurrences] => 1
        )

)

正如您所看到的,两个阵列中的列相同(team,team_points,team_occurrences)

现在,我想将这两个数组合并到名为 $ list_all

的数组中

合并的问题是我尝试过的标准合并

array_merge($list,$list2);

将它们加在一起。

然而,我需要的是统计相同的团队,例如 [团队] => 14 [团队] => 13 在两个数组中(在$ list和$ list2中),因此,我需要将$ list中的 team_points 列值与 team_points 列值相加如果团队相同,则来自$ list2。 team_occurrences 列也是如此。

所以,例如

新数组看起来不像这样:

Array
(
[0] => Array // from $list
    (
        [team] => 14
        [team_points] => 3
        [team_occurrences] => 2
    )

[1] => Array // from $list2
    (
        [team] => 14
        [team_points] => 3
        [team_occurrences] => 1
    )

[3] => Array // from $list
    (
        [team] => 13
        [team_points] => 1
        [team_occurrences] => 1
    )

[4] => Array // from $list2
    (
        [team] => 13
        [team_points] => 3
        [team_occurrences] => 1
    )

但我需要它看起来像这样:

Array
(
[0] => Array 
    (
        [team] => 14
        [team_points] => 6
        [team_occurrences] => 3
    )

[1] => Array 
    (
        [team] => 13
        [team_points] => 4
        [team_occurrences] => 2
    )

在合并之后,我想使用usort()对结果数组进行排序,或者通过team_points DESC(从最高值到最低值)对某些更好的函数进行排序。

提前感谢任何建议。

3 个答案:

答案 0 :(得分:2)

迭代第一个列表,创建一个新数组,其键是团队编号。然后迭代第二个数组,如果团队已经存在,则添加,否则,追加。

$combined = array();
// First loop creates array keys in $combined array
// based on team numbers
foreach($list as $initial) {
  $combined[$initial['team']] = $initial; 
}

// Second loop looks at $list2 and either adds to values
// if the team key already exists, or just adds the 
// whole subarray on if it doesn't.
foreach($list2 as $secondary) {
  // If it was in the first, append to it.
  if (isset($combined[$secondary['team']])) {
    $combined[$secondary['team']]['team_points'] += $secondary['team_points'];
    $combined[$secondary['team']]['team_occurrences'] += $secondary['team_occurrences'];
  }
  // Otherwise, just add it to the array
  else {
    $combined[$secondary['team']] = $secondary;
  }
}

// Then sort the combined array with usort() into descending order by points
// Anonymous callback function is PHP 5.3+. Needs to be a string value of a named function
// for PHP < 5.3
usort($combined, function($a, $b) {
  if ($a['team_points'] === $b['team_points']) {
     return 0;
  }
  else {
     return $a['team_points'] < $b['team_points'] ? 1 : -1;
  }
});

注意:上面会生成一个由团队编号键入的输出数组。如果您真的只想提升数字键,请在其上调用array_values()

// Strip off the team number keys and just use ascending numbers
$combined = array_values($combined);

编辑修复了上面遗漏的一些] ...

答案 1 :(得分:1)

最简单的是在团队编号上对两个数组进行排序(使用usort)。同时遍历两个阵列并选择最低的团队编号。如果list1最低,请将该团队添加到结果中并增加list1索引。如果list2最低,请将该团队添加到结果中并增加list2索引。如果两个团队相同,则通过添加点和事件来组合它们。重复,直到您在一个列表的末尾,并添加其他列表中剩余的元素。

答案 2 :(得分:1)

您可以通过以下方式执行此操作:

foreach($list2 as $ky => $val) {
    $list2['t'.$val['team']] = $val;
}

$tot = count($list1);
$list3 = array();
for ($i=0;$i<$tot;$i++) {
    $team = $list1[$i]['Team'];
    $list3[]['Team'] = $team;
    $points = isset($list2['t'+$team]) ? $list2['t'+$team]['team_points'] : 0;
    $list3[]['team_points'] = $list1[i]['team_points'] + $points;
    $ocu = isset($list2['t'+$team]) ? $list2['t'+$team]['team_ocurrences'] : 0;
    $list3[]['team_ocurrences'] = $list1[$i]['team_ocurrences'] + $ocu;
}

function cmp($a, $b) {
    if ($a['team_points'] == $b['team_points']) {
        return 0;
    }
    return ($a['team_points'] > $b['team_points']) ? -1 : 1;
}

usort($list3, "cmp");