简体   繁体   中英

Group arrays based on similar values in PHP

I have an array with this structure:

<?php
$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' => 5,
            'teacher' => 'John',
        )
    );

where I want to group them based on certain attributes. For example to group all grades which have same number of students would be :

Grade 1 Class - Grade 3 Class     5

I got through the array like this:

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

foreach ($return as $key => $value) {
   echo implode(' - ', $value)."\t\t".$key;
}
// output is 
// Grade 1 Class - Grade 2 Class - Grade 3 Class      5

but the above code outputs the middle grade as well, how can I only output the first and last elements to get the desired output assuming we may not know where the similar values occurs?

For example, for this array this is the desired output:

Grade 1 Class - Grade 2 Class     5
Grade 3 Class - Grade 6 Class     8
Grade 7 Class                     9 
Grade 8 Class - Grade 9 Class     4 

As mentioned in question, you need only first and last element. First you need to group array according to student id and than print first and last element. I have update your code as -

$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' => 'John',
    ),
);

$newArray = array();
$keyIndex = 0;
$s = null;
foreach ($grades as $key => $value) {
    if($s != $value['students']){
        $keyIndex++;
    }
    $newArray[$keyIndex][] = $value;
    $s = $value['students'];
}

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'] .' '. $lastGrade['students'];
    }
    else{
        echo $data[$gradeFirst]['title'] .' '. $data[$gradeFirst]['students'];
    }
    echo "<br>";
}

First loop group all element according to student. Second Loop print output on screen. If condition is added in second loop if for check that there is single grade or multiple grade for a student.

It return output as

Grade 1 Class - Grade 2 Class 5
Grade 3 Class - Grade 6 Class 8
Grade 7 Class 9
Grade 8 Class 4

This works for me

<?php

$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' => 5,
            'teacher' => 'Tina',
        )
    );


foreach ( $grades as $outer_k => $outer_v ) {
    // hold current $outer_k and start looping through $grades agaain, doing
    // comparison
    foreach ( $grades as $inner_k => $inner_v ) {
        // check inner_k is not comparing itself to itself
        if ( $inner_k !== $outer_k ) {
            if ( $inner_v['students'] === $outer_v['students'] ) {
                $matches[] = $inner_v['title'];
                $num_students = $inner_v['students'];
            }
        }
    }
}

sort($matches);
$result = array_unique($matches);
$result = array_values($result);

$length = count($result) - 1;
echo $result[0] . " - " . $result[$length] . "\t\t{$num_students}\n";

produces this output:

Grade 1 Class - Grade 4 Class           5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM