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


Merge array-of-array with specifics similar values

假设我有这样一个数组:

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

在我的代码中,我需要合并用户(相同的名字+相同的年龄)或(相同的电子邮件),以求和点并返回该用户的唯一副本,考虑到该用户的最新信息,如果合并。

所以,注意:

  • User#0可以与User#2合并,因为它们具有(同姓+同岁);
  • User#0不能直接与User#3合并,因为它们没有相似性;
  • User#2可以与User#3合并,因为它们共享(相同的电子邮件);
  • 因此,间接地,User#0 可以与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不重要

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

$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