合并具有类似值的特定数组的数组

时间:2014-08-18 19:54:44

标签: php

想象一下,我有这个数组:

$users = [];
$users[0] = [ "Name" => "John Doe", "Age" => 48, 
              "Email" => "john.doe@server-a.com", "Points" => 5 ];
$users[1] = [ "Name" => "John Brother", "Age" => 32, 
              "Email" => "john.brother@server-a.com", "Points" => 8 ];
$users[2] = [ "Name" => "John Doe", "Age" => 48, 
              "Email" => "john.doe@server-b.com", "Points" => 3 ];
$users[3] = [ "Name" => "John Doe", "Age" => 49, 
              "Email" => "john.doe@server-b.com", "Points" => 7 ];

在我的代码中,我需要在(同名+相同年龄)或(相同电子邮件)时合并用户,以汇总点并返回此用户的唯一副本,考虑此用户的最新信息(如果已合并)。 / p>

所以,请注意:

  • User#0可以与User#2合并,因为它共享(同名+相同年龄);
  • User#0无法将直接User#3合并,因为它们没有相似性;
  • User#2可以与User#3合并,因为它共享(相同的电子邮件);
  • 因此,间接地User#0 CAN User#3User#2合并;

预期结果是:

$users[] = [ "Name" => "John Brother", "Age" => 32, 
             "Email" => "john.brother@server-a.com", "Points" => 8 ];
$users[] = [ "Name" => "John Doe", "Age" => 49, 
             "Email" => "john.doe@server-b.com", "Points" => 15 ];

注意:合并后的User#ID并不重要。

1 个答案:

答案 0 :(得分:0)

我不确定是否有更高效或更优雅的方法,但你可以尝试这样的事情:

$result = [];
$tmp = [];
array_walk($users, function ($value) use (&$result, &$tmp) {
    $hash = md5($value['Name'].$value['Age']);
    $sum  = $value['Points'];
    $e    = $value['Email'];
    if (array_key_exists($hash, $result)) {
        $sum += $result[$hash]['Points'];
    } elseif (array_key_exists($e, $tmp)) {
        $hash = md5($tmp[$e]['Name'].$tmp[$e]['Age']);
        $sum += $result[$hash]['Points'];
    }
    $result[$hash] = $tmp[$e] = $value;
    $result[$hash]['Points'] = $sum;
});

$users = array_values($result);
var_dump($users);

输出结果为:

array (size=2)
  0 => 
    array (size=4)
      'Name' => string 'John Doe' (length=8)
      'Age' => int 49
      'Email' => string 'john.doe@server-b.com' (length=21)
      'Points' => int 15
  1 => 
    array (size=4)
      'Name' => string 'John Brother' (length=12)
      'Age' => int 32
      'Email' => string 'john.brother@server-a.com' (length=25)
      'Points' => int 8