Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have an array AllUsers as

Array AllUsers
(
    [0] => Array
         (
             [0] => Array
                  (
                      [0] => Tim
                      [1] => [email protected]
                  )
             [1] => Array
                  (
                      [0] => John
                      [1] => [email protected]
                  )
         )
    [1] => Array
         (
             [0] => Array
                  (
                      [0] => Mike
                      [1] => [email protected]
                  )
             [1] => Array
                  (
                      [0] => Aron
                      [1] => [email protected]
                  )
         )
)

I have another array FilteredUsers as

Array FilteredUsers
(
    [0] => Array
         (
             [0] => John
             [1] => [email protected]
         )
    [1] => Array
         (
             [0] => Mike
             [1] => [email protected]
         )
    [2] => Array
         (
             [0] => Mike
             [1] => [email protected]
         )
)

Now what I want is to add every element of FilteredUsers[] in AllUsers[] such that -

  1. FilteredUsers[0] should get added to Batch AllUsers[1] because Batch AllUsers[0] already has array with element name John in it
  2. Similarly FilteredUsers[1] should get added to Batch AllUsers[0]
  3. Any Batch (like AllUsers[0], AllUsers[1]) can't have more than 3 elements. If all Batches are full, then a new batch shall be created but every element in FilteredUsers[] should be accommodated in some Batch.

So the updated AllUsers array should be something like this -

Array AllUsers
(
    [0] => Array
         (
             [0] => Array
                  (
                      [0] => Tim
                      [1] => [email protected]
                  )
             [1] => Array
                  (
                      [0] => John
                      [1] => [email protected]
                  )
             [2] => Array
                  (
                      [0] => Mike
                      [1] => [email protected]
                  )
         )
    [1] => Array
         (
             [0] => Array
                  (
                      [0] => Mike
                      [1] => [email protected]
                  )
             [1] => Array
                  (
                      [0] => Aron
                      [1] => [email protected]
                  )
             [2] => Array
                  (
                      [0] => John
                      [1] => [email protected]
                  )
         )
    [2] => Array
         (
             [0] => Array
                  (
                      [0] => Mike
                      [1] => [email protected]
                  )
         )
)
share|improve this question
1  
Just a curiosity, why do you need batches of 3 ? You can easily do a for($i = 0; $i <= count($AllUsers), $i += 3){} –  Vlad Preda Jan 17 '13 at 15:12
add comment

2 Answers

up vote 2 down vote accepted

Here is the working code:

I have created a code pastebin also for you at: http://codepad.org/iyZUpYxc

<?php

//PHP Multidimensional Array Manipulation

$allUsers = array();
$allUsers[] = array(array('name'=>'Tim', 'email'=>'[email protected]'), array('name'=>'John','email'=>'[email protected]'));
$allUsers[] = array(array('name'=>'Mike', 'email'=>'[email protected]'), array('name'=>'Aron','email'=>'[email protected]'));

$filteredUsers = array();
$filteredUsers[] = array('name'=>'John', 'email'=>'[email protected]');
$filteredUsers[] = array('name'=>'Mike', 'email'=>'[email protected]');
$filteredUsers[] = array('name'=>'Mike', 'email'=>'[email protected]');

//RULE: one batch cannot have duplicate user names

//print_r($allUsers);
//print_r($filteredUsers);

foreach ($filteredUsers as $filteredUser) {
  //$filteredUser is a single dimensional arrray.

  $filteredUserAdded = 0;
  foreach ($allUsers as &$allUser) {
     //$allUser is a muldimentional array.

     //Check whether the current batch contains $filteredUser['name'] value
     $intersect = array_uintersect(array($filteredUser), $allUser, 'compareName');
     if (empty($intersect) && count($allUser) < 3) {
         //We can add filtereduser here
         $allUser[] = $filteredUser; 
         $filteredUserAdded = 1;
     }

  } // end foreach $allUsers

  if ($filteredUserAdded == 0) {
      //This filtered user was not added in any existing batch.
      //Hence add it in a new batch
      $allUsers[] = array($filteredUser);       
  }
} // end foreach $filteredUsers


//function to compare the 'name' column value of two arrays
function compareName($array1, $array2)
{
   return strcmp($array1['name'], $array2['name']);
}

//Note: http://in1.php.net/array_uintersect is the key used here for comparison

print_r($allUsers);
print_r($filteredUsers);

?>

Note: You have missed the array ( [0] => John [1] => [email protected] ) in your Output above.

But my code outputs that also correctly.

Thanks

share|improve this answer
    
@Sachyn Please let me know about the success of this code :) –  OMG Jan 17 '13 at 19:13
    
OMG it works.. thanks so much :) –  Sachyn Kosare Jan 18 '13 at 7:06
    
Thanks for vote @Sachyn –  OMG Jan 18 '13 at 7:09
add comment

Challenge Accepted!!!

##### BORROWED FROM OMG
//PHP Multidimensional Array Manipulation

$allUsers = array();
$allUsers[] = array(array('name'=>'Tim', 'email'=>'[email protected]'), array('name'=>'John','email'=>'[email protected]'));
$allUsers[] = array(array('name'=>'Mike', 'email'=>'[email protected]'), array('name'=>'Aron','email'=>'[email protected]'));

$filteredUsers = array();
$filteredUsers[] = array('name'=>'John', 'email'=>'[email protected]');
$filteredUsers[] = array('name'=>'Mike', 'email'=>'[email protected]');
$filteredUsers[] = array('name'=>'Mike', 'email'=>'[email protected]');

# using PHP's unique continue statement!    

# loop through filtered users
foreach($filteredUsers as $fUser) {
     #loop through all users batches
     foreach($allUsers as $key=>$aUsers) {
        # is it full?
        if(isset($aUsers[2]))continue;
        # any user with same name?
        foreach($aUsers as $aUser)
            if($aUser['name']==$fUser['name'])continue 2;
        # push in current batch
        $allUsers[$key][]=$fUser;
        continue 2;
    }
    # new batch needed
    $allUsers[]=$fUser;
}
var_dump($allUsers);

In case you didn't know, continue accepts an "argument" representing the number of control flows to bubble up to.

And working code can be found here.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.