将多个阵列拆分为唯一的组


Split Multiple Arrays Into Unique Groups

我很难想出这个问题的解决方案(可能是因为今天是星期一)。我有多个用户成员数组(电子邮件地址),我想把它们分成唯一的组。

数据的例子:

$members = array(
    'Group One' => array(
        'User A',
        'User B',
        'User C',
        'User D'
    ),
    'Group Two' => array(
        'User A',
        'User B',
        'User D'
    ),
    'Group Three' => array(
        'User A',
        'User E'
    )
);    

现在我想把它们分成不同的组,得到这样的结果:

Array (
    0 => Array (
        'Groups' => Array (
            0 => 'Group One'
        ),
        'Members' => Array (
            0 => 'User C'
        )
    ),
    1 => Array (
        'Groups' => Array (
            0 => 'Group One',
            1 => 'Group Two'
        ),
        'Members' => Array (
            0 => 'User B',
            1 => 'User D'
        )
    ),
    2 => Array (
        'Groups' => Array (
            0 => 'Group One',
            1 => 'Group Two',
            2 => 'Group Three'
        ),
        'Members' => Array (
            0 => 'User A'
        )
    ),
    3 => Array (
        'Groups' => Array (
            0 => 'Group Three'
        ),
        'Members' => Array (
            0 => 'User E'
        )
    )
)

看起来这是你想要的。我们将所有组的唯一组合放入$pool数组中。在getValues函数中,我们从$a中的池(与数组相交)中获得存在于每个组中的值,并且我们在$b中获得来自其他组(与数组合并)的所有值。然后使用array_diff.

返回池中每个组中存在的用户,而不是其他组中的用户。
<?php
$members = array(
    'Group One' => array(
        'User A',
        'User B',
        'User C',
        'User D'
    ),
    'Group Two' => array(
        'User A',
        'User B',
        'User D'
    ),
    'Group Three' => array(
        'User A',
        'User E'
    )
);
$keys = array_keys($members);
$len = count($keys);
function getValues(&$result = array(), $members, $pool) {
    $a = null;
    $b = array();
    foreach ($members as $group => $values) {
        if (in_array($group, $pool)) {
            $a = (null === $a) ? $values : array_intersect($a, $values);
        } else {
            $b = array_merge($b, $values);
        }
    }
    if ($ret = array_diff($a, $b)) {
        $result[] = array(
            'Groups' => $pool,
            'Members' => array_values($ret),
        );
    }
}
for ($i = 0; $i < $len; ++$i) {
    $pool = array($keys[$i]);
    for ($j = $i; $j < $len; ++$j) {
        if ($j > $i) {
            $pool[] = $keys[$j];
        }
        getValues($result, $members, $pool);
    }
}
print_r($result);

输出如下:

Array
(
    [0] => Array
        (
            [Groups] => Array
                (
                    [0] => Group One
                )
            [Members] => Array
                (
                    [0] => User C
                )
        )
    [1] => Array
        (
            [Groups] => Array
                (
                    [0] => Group One
                    [1] => Group Two
                )
            [Members] => Array
                (
                    [0] => User B
                    [1] => User D
                )
        )
    [2] => Array
        (
            [Groups] => Array
                (
                    [0] => Group One
                    [1] => Group Two
                    [2] => Group Three
                )
            [Members] => Array
                (
                    [0] => User A
                )
        )
    [3] => Array
        (
            [Groups] => Array
                (
                    [0] => Group Three
                )
            [Members] => Array
                (
                    [0] => User E
                )
        )
)

这可能不是最好的解决方案,但应该可以工作。首先,创建一个助手数组,按用户(而不是按组)对数据进行分组,以找出每个用户的组组合。然后,遍历结果数组并构建结果。

$members = array(
    'Group One' => array(
        'User A',
        'User B',
        'User C',
        'User D'
    ),
    'Group Two' => array(
        'User A',
        'User B',
        'User D'
    ),
    'Group Three' => array(
        'User A',
        'User E'
    )
);
$uniqueGroups = array();
$groupedByUser = array();
foreach($members as $group => $users) {
    foreach($users as $user) {
        if(!is_array($groupedByUser[$user])) {
            $groupedByUser[$user] = array();
        }
        $groupedByUser[$user][] = $group;
    }
}
foreach($groupedByUser as $user => $groups) {
    sort($groups);
    $found = FALSE;
    foreach($uniqueGroups as $idx=>&$infos) {
        $currentGroups = $infos['Groups'];
        $diff = array_diff($currentGroups, $groups);
        if(empty($diff)) {
            $infos['Users'][] = $user;
            $found = TRUE;
        }
    }
    if(!$found) {
        $uniqueGroups[] = array(
            'Groups' => $groups,
            'Users' => array($user)
        );
    }
}
print_r($uniqueGroups);