Skip to content
Advertisement

Group and sort multiple associative arrays in PHP based on two conditions

I have couple of associative arrays like this

$arrayOne = array (
    "name" => 'john',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'math',
);

$arrayTwo = array (
    "name" => 'smith',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'science',
);  

$arrayThree = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2009',
    "department" => 'math',
);  

$arrayFour = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2011',
    "department" => 'math',
); 

I want to get the arrays that have the latest hired year, and also based on the department order.

so the department priorities are ['math', 'science', 'social'] (ordered based on priority)

If only one array has recent years: For example from the above array we only get this one:

$arrayFour = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2011',
    "department" => 'math',
); 

since this one is the only one that has most recent hired year, we dont care about the department.

But if there are multiple arrays with same year, then we look at the department.

$arrayOne = array (
    "name" => 'john',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'math',
);

$arrayTwo = array (
    "name" => 'smith',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'science',
);  

$arrayThree = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'math',
);  

$arrayFour = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'social',
); 

Since we have arrays with 2010 as hired year, I want to get the ones which are under math department. Since math is first in the department order, if there were no math, we would get the ones with science, if no science then social. We would just get $arrayOne and $arrayThree in this example.

I started by creating a function but I am confused how to check against the year and department

function instructors($arrays){
    
    foreach ($arrays as $array){
        // how to check for recent year?
        if($array['hired']){
            
        }
    }
}
var_dump(instructors($arrayOne, $arrayTwo, $arrayThree, $arrayFour ));

Advertisement

Answer

I have written the following code:

The getResult method first checks if of the most recent year there is one item, if so, it returns this one item. If not it will loop through the array based on the department order and returns the first items that are present.

$arrayOne = array (
    "name" => 'john',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'math',
);

$arrayTwo = array (
    "name" => 'smith',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'science',
);  

$arrayThree = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'math',
);  

$arrayFour = array (
    "name" => 'dave',
    "position" => 'instructor',
    "hired"  => '2010',
    "department" => 'social',
); 

function getLatestHiredYear(...$arrays) : int 
{
    return (int) max(array_column($arrays, "hired"));
}

function getArraysBasedOnDepartment(int $year, string $department, ...$arrays) : array 
{
    $return = [];
    foreach($arrays as $array) {
        if($array['department'] == $department && $array['hired'] == $year) {
            $return[] = $array;
        }
    }
    return $return;
}

function getResult(...$arrays) : array 
{
    $orderItems = ['math', 'science', 'social'];
    $return = [];
    $recentYear = getLatestHiredYear(...$arrays);

    $grouped = [];
    foreach($arrays as $array) {
        $grouped[$array['hired']][] = $array;
    }

    //only one of recent year
    if(count($grouped[$recentYear]) === 1) {
        return $grouped[$recentYear];
    }

    //Multiple items for year 
    foreach($orderItems as $department) {
        $departmentArrays = getArraysBasedOnDepartment($recentYear, $department, ...$arrays);
        if(!empty($departmentArrays)) {
            $return = $departmentArrays;
            break;
        }
    }

    return $return;
}

var_dump(getResult($arrayOne, $arrayTwo, $arrayThree, $arrayFour));

Output:

array(2) {
  [0]=>
  array(4) {
    ["name"]=>
    string(4) "john"
    ["position"]=>
    string(10) "instructor"
    ["hired"]=>
    string(4) "2010"
    ["department"]=>
    string(4) "math"
  }
  [1]=>
  array(4) {
    ["name"]=>
    string(4) "dave"
    ["position"]=>
    string(10) "instructor"
    ["hired"]=>
    string(4) "2010"
    ["department"]=>
    string(4) "math"
  }
}
User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement