I'm having a few issues writing accurate and efficient code in PHP for this problem below.
I have a list of users, and each user has a list of friends. I want to group all the friends into groups where each person has at least one friend with another user.
Below is a simplified array, with unneeded array keys removed and user id's replaced with names.
Array
[Ted] => Array
[friends] => Array
[0] => Sarah
[John] => Array
[friends] => Array
[0] => Peter
[1] => Sam
[Peter] => Array
[friends] => Array
[0] => John
[1] => Sam
[Frank] => Array
[friends] => Array
[0] => Bob
[1] => Sarah
[Kevin] => Array
[friends] => Array
[0] => Sally
[Sam] => Array
[friends] => Array
[0] => John
[1] => Peter
[Bob] => Array
[friends] => Array
[0] => Frank
[1] => Sarah
[Sarah] => Array
[friends] => Array
[0] => Frank
[1] => Bob
[2] => Ted
[3] => Jane
[Sally] => Array
[friends] => Array
[0] => Kevin
[Jane] => Array
[friends] => Array
The output of this should be as follows:
Group 1: Sarah, Frank, Bob, Jane, Ted
Group 2: John, Peter, Sam
Group 3: Sally, Kevin
As a note, there is no data for Jane, but Sarah is friends with her so this grouping can happen. Also There will be users with no friends, they should be placed in there own group.
I have tried to write code for this, but it is very inefficient and contains three nested foreach loops. I am quite ashamed :(
$friendGroups = [];
foreach($userdata as $key => $user)
{
$friends = $user["friends"];
// Loop the current groups
foreach($friendGroups as $friendkey => $friendValue)
{
// Does the group contain any of the friends?
foreach($friends as $friendID)
{
if (array_key_exists($friendID, $friendValue))
{
// add the friends to this group
foreach($friends as $friendIDx)
{
$friendGroups[$friendkey][$friendIDx] = $userdata[$friendIDx];
}
continue 3;
}
}
}
$groupID = count($friendGroups);
// Create a new group
foreach($friends as $friendID)
{
$friendGroups[$groupID][$friendID] = $userdata[$friendID];
}
}