0

I have an array with this structure:

$grades = array(
        'Grade 1'  => array(
            'title'   => 'Grade 1 Class',
            'students' => 5,
            'teacher' => 'Smith',
        ),
        'Grade 2' => array(
            'title'   => 'Grade 2 Class',
            'students' => 5,
            'teacher' => 'Smith',
        ),
        'Grade 3' => array(
            'title'   =>'Grade 3 Class',
            'students' => 8,
            'teacher' => 'John',
        ),
        'Grade 4' => array(
            'title'   =>'Grade 4 Class',
            'students' => 8,
            'teacher' => 'John',
        ),
        'Grade 5' => array(
            'title'   =>'Grade 5 Class',
            'students' => 8,
            'teacher' => 'John',
        ),
        'Grade 6' => array(
            'title'   =>'Grade 6 Class',
            'students' => 8,
            'teacher' => 'John',
        ),
        'Grade 7' => array(
            'title'   =>'Grade 7 Class',
            'students' => 9,
            'teacher' => 'John',
        ),
        'Grade 8' => array(
            'title'   =>'Grade 8 Class',
            'students' => 4,
            'teacher' => 'Tina',
        ),
       'Grade 9' => array(
            'title'   =>'Grade 9 Class',
            'students' => 4,
            'teacher' => 'Tina',
        )
    );

And I want to group them based on both number of students and teacher.

For example the above array should output this:

Grade 1 Class - Grade 2 Class     5   Smith  // group 1
Grade 3 Class - Grade 6 Class     8   John   // group 2
Grade 7 Class                     9   John   // group 3
Grade 8 Class - Grade 9 Class     4   Tina   // group 4

so to be in 1 group, they must have both same number of students and same teacher.

The following only groups based on number of students (it also has some bugs):

$newArray = array();
foreach ($grades as $key => $value) {
    $newArray[$value['students']][$key] = $value;
}

foreach ($newArray as $student => $data) {
    $gradeFirst =  key($data);
    // Check there are multiple grade or single grade
    if(count($data) > 1){
        $lastGrade = end($data);
        echo $data[$gradeFirst]['title'].' - '.$lastGrade['title'] .' '. $student;
    }
    else{
        echo $data[$gradeFirst]['title'].' '. $student;
    }
    echo "\n";
}

how can I make sure both student and teacher are used for grouping?

Note: the order is important, so for example, there won't be a group for class 1, class 3, class 4, if class 2 is different. In that case it would be :

Grade 1 Class                      // group 
Grade 2 Class                      // breaks the group 
Grade 3 Class - Grade 4 Class      // rest of the group

1 Answer 1

2
$newArray = [];
foreach($grades as $grade_key => $grade) {
    $group_key = $grade['teacher'].'_'.$grade['students'];
    if(!isset($newArray[$group_key]))
        $newArray[$group_key] = [];
    $newArray[$group_key][$grade_key] = $grade;
}
print_r($newArray); //just to check groupping is correct

I'd group them like this, by teacher and students count.

But some words about you output format... what if grades 1, 3 and 5 should be in one group, and 2 and 4 - in another? You cant output them like Grade 1 Class - Grade 4 Class, so you should choose more flexible output format.

UPD but if you want to break group as you wrote in question update - try this:

$newArray = [];
$prev_group_key = '';
$group_key_appendix = 0;
foreach($grades as $grade_key => $grade) {
    $group_key = $grade['teacher'].'_'.$grade['students'];

    // perform group key unicalization in case tha groupping condition is the same but group should break
    if($group_key !== $prev_group_key) 
        $group_key_appendix++;
    $prev_group_key = $group_key;
    $real_group_key = $group_key.'-'.$group_key_appendix;

    if(!isset($newArray[$real_group_key]))
        $newArray[$real_group_key] = [];
    $newArray[$real_group_key][$grade_key] = $grade;
}
print_r($newArray);
Sign up to request clarification or add additional context in comments.

6 Comments

thanks for your comment, regarding your question "what if grades 1, 3 and 5 should be in one group" they can't. They only can be in a group if they are in order, else they will have their own groups.
well, in such case you could just replace you groupping code by code I wrote above. Also I've fixed it a little to fit you output code.
wait, you added new groupping condition, I've not implemented it yet...
Thank you for the explanation
is there a way I can contact you directly?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.