1

As shown below I have a multi-dimensional array with an associative array in the third level that I am trying to manipulate based on gamesCount. I want to generate a new array of items with the highest gamesCount in each sport. Is there an efficient way to this without going overkill?

EDIT: It could be n number of sports hence the goal is to find the max number for gameCounts for each sport.

Initial array:

$array = [
    [
        ["sport" => "soccer", "gamesCount" => 5, "gamesId" => 1],
        ["sport" => "soccer", "gamesCount" => 3, "gamesId" => 2],
        ["sport" => "soccer", "gamesCount" => 10, "gamesId" => 3],
        ["sport" => "soccer", "gamesCount" => 10, "gamesId" => 4],
    ],
    [
        ["sport" => "basketball", "gamesCount" => 1, "gamesId" => 5],
        ["sport" => "basketball", "gamesCount" => 3, "gamesId" => 6],
        ["sport" => "basketball", "gamesCount" => 3, "gamesId" => 7],
        ["sport" => "basketball", "gamesCount" => 8, "gamesId" => 8],
    ]
];

Desired Result:

array(3) {
      [0]=>
      array(3) {
        ["sport"]=>
        string(6) "soccer"
        ["gamesCount"]=>
        int(10)
        ["gamesId"]=>
        int(3)
      }
      [1]=>
      array(3) {
        ["sport"]=>
        string(6) "soccer"
        ["gamesCount"]=>
        int(10)
        ["gamesId"]=>
        int(4)
      }
      [2]=>
      array(3) {
        ["sport"]=>
        string(10) "basketball"
        ["gamesCount"]=>
        int(5)
        ["gamesId"]=>
        int(8)
      }
}
0

2 Answers 2

1

try this, check the live demo

$result = [];
foreach($array as $v)
{
$max = max(array_column($v, 'gamesCount'));
    $result = array_merge($result, array_filter($v, function($value)use($max){return $value['gamesCount'] == $max;}));
}
var_dump($result);
Sign up to request clarification or add additional context in comments.

7 Comments

I am getting an error: Warning: max(): Array must contain at least one element for this line return max(array_column($v, 'gameCount'));. I double checked and $array does contain an array an its elements.
@MaryCoding there is a error, it should be gamesCount in the code.
It yields an empty array. Check this GIST
@KrisRoofe No Kris, check the edit history. Same structure. Now she is using my php-ready variable instead of the print_r output that she first posted. The sports were always in two separate subarrays.
@mickmackusa sorry, I miss use a function. check it now
|
1

Input:

$array=[
    [
        ["sport"=>"soccer","gamesCount"=>5,"gamesId"=>1],
        ["sport"=>"soccer","gamesCount"=>3,"gamesId"=>2],
        ["sport"=>"soccer","gamesCount"=>10,"gamesId"=>3],
        ["sport"=>"soccer","gamesCount"=>10,"gamesId"=>4]
    ],
    [
        ["sport"=>"basketball","gamesCount"=>1,"gamesId"=>5],
        ["sport"=>"basketball","gamesCount"=>3,"gamesId"=>6],
        ["sport"=>"basketball","gamesCount"=>3,"gamesId"=>7],
        ["sport"=>"basketball","gamesCount"=>8,"gamesId"=>8]
    ]
];

Method #1 "The easiest to read version with two loops" (Demo)

foreach($array as $sport_array){
    $most_in_sport=max(array_column($sport_array,'gamesCount'));  // get highest gamesCount in sport's subarray      
    foreach($sport_array as $sport_row){
        if($sport_row['gamesCount']==$most_in_sport){  // only keep a sport's subarray (row) if its gamesCount is the highest in the sport
            $most_per_sport[]=$sport_row;
        }
    }
}
var_export($most_per_sport);

Method #2: "The obscenely convoluted variadic one-liner" php minimum version: 5.6 (For those who wish who do not fear the one-liner apocalypse -- reference: 1st comment @ https://stackoverflow.com/a/43950486/2943403.) (Demo)

var_export(array_merge(...array_map(function($sport_array){$most_in_sport=max(array_column($sport_array,'gamesCount')); return array_filter($sport_array,function($sport_row)use($most_in_sport){return $sport_row['gamesCount']==$most_in_sport;});},$array)));

Output:

array (
  0 => 
  array (
    'sport' => 'soccer',
    'gamesCount' => 10,
    'gamesId' => 3,
  ),
  1 => 
  array (
    'sport' => 'soccer',
    'gamesCount' => 10,
    'gamesId' => 4,
  ),
  2 => 
  array (
    'sport' => 'basketball',
    'gamesCount' => 8,
    'gamesId' => 8,
  ),
)

Deciding which method to use is up to each individual programmer. The first method will be most efficient and IMO easiest to comprehend. The second will generate less global variables and require less lines of code. If you are trying to avoid "over-kill" Method #1 cannot be beaten.

5 Comments

This only handles two arrays but thing is that it could be n number of arrays. E.g. basketball, soccer, baseball, etc.
@MaryCoding What do you think now? I have provided two methods to suit a range of php versions.
This got me closer to a result but this is line is hardcoded $top3 = array_slice($array, 0, 3); // extract the top 3 subarrays. It could be n number of sports hence n number of max for gameCounts. Specially if there are the same value for some.
@MaryCoding You never said in your question where to draw the line, so I replicated your desired result. You can change it to whatever you like.
You are correct. My apologies. I will update the question. Thanks.

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.