将多个阵列拆分为唯一组

时间:2014-03-24 14:17:01

标签: 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'
    )
);    

现在我想将它们分成独特的组并得到如下结果:

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'
        )
    )
)

2 个答案:

答案 0 :(得分:1)

看起来这样做你想要的。 我们将所有组的唯一组合转换为$ 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
                )

        )

)

答案 1 :(得分:0)

这可能不是最佳解决方案,但这应该有效。 首先,创建一个辅助数组,按用户而不是按组对数据进行分组,以找出每个用户的组合。然后,遍历生成的数组并构建结果。

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