Students Position From Average

Published 5 days ago by InspiredPrynce

Please i have a data like this..

array:9 [
    3101625668 => 98.0,
    3101635921 => 98.0,
    3913126364 => 35.77,
    3913058204 => 25.33,
    3101372540 => 33.47,
    3913752741 => 40.0,
    3913120054 => 20.4,
    3913998755 => 26.67,
    3913861492 => 25.2,
    3913881854 => 19.8,
]

I want to get the students position from the average. The array keys represent the student PIN Number and the value is their average. In array[0] and array[1], the values are the same and i want to get something like "1st" twice then "3rd"...

Someone help me please, have been awake all night working on this...

@andreasbakir thanks for the previous help you rendered! I appreciate man!

I really need help with this one!

Best Answer (As Selected By InspiredPrynce)
Vilfago
$array_results = [3101625668 => 98.0, 3101635921 => 98.0, 3913126364 => 35.77, 3913058204 => 25.33, 3101372540 => 33.47, 3913752741 => 40.0, 3913120054 => 20.4, 3913998755 => 26.67, 3913861492 => 25.2, 3913881854 => 19.8,];
        
        $results = collect($array_results);

        $results_sorted = $results->sort()->reverse();

        $current_rank = 1;
        $number_in_position = 0;

        $max_score = 100;
        $current_score = $max_score;

        foreach($results_sorted as $pin => $result)
        {
                if($result < $current_score ){
                        $current_score = $result;
                        $current_rank += $number_in_position;
                        $number_in_position = 1;
                        $output[$pin] = [$current_rank, $result];
                }else{ //same score as the previous
                        $number_in_position++;
                        $output[$pin] = [$current_rank, $result];
                }
        }

        dd($output);
Vilfago
Vilfago
5 days ago (49,800 XP)

Sort your data by values : https://laravel.com/docs/5.7/collections#method-sort And then you can loop trough it, and implement a counter for the ranking.

InspiredPrynce

@Vilfago i would really appreciate it if you can show me a working example. I've been at it since, have sorted the shit outta this array. Please help...

Vilfago
Vilfago
5 days ago (49,800 XP)

Could you provide me the output you want ? An array with a sub-array containing pin and value ? Key as rank, or value for rank?

InspiredPrynce

@Vilfago i want an output like this..

array:10 [
    3101625668 => ["1st", 98.0],
    3101635921 => ["1st", 98.0],
    3913126364 => ["4th", 35.77],
    3913058204 => ["7th", 25.33],
    3101372540 => ["5th", 33.47],
    3913752741 => ["3rd", 40.0],
    3913120054 => ["9th", 20.4],
    3913998755 => ["6th", 26.67],
    3913861492 => ["8th", 25.2],
    3913881854 => ["10th", 19.8]
]
Vilfago
Vilfago
5 days ago (49,800 XP)
$results = collect([$array_results]);

$results_sorted = $results->sort()->reverse();

$current_rank = 1;
$number_in_position = 0;
$current_score = 100;

foreach($results_sorted as $pin => $result)
{
    if($result < $current_score){
        $current_score = $result;
        $current_rank += $number_in_position
        $number_in_position = 1;
        $output[$pin] = [$current_rank, $result];
        ++;
    }else{ //same score as the previous
        $number_in_position++;
        $output[$pin] = [$current_rank, $result];
    }
}

dd($output);

I didn't test it, I let you some job (test, debug, optimize)

burlresearch
    public function handle() {
        $marks = collect([3101625668 => 98.0, 3101635921 => 98.0, 3913126364 => 35.77, 3913058204 => 25.33, 3101372540 => 33.47, 3913752741 => 40.0, 3913120054 => 20.4, 3913998755 => 26.67, 3913861492 => 25.2, 3913881854 => 19.8,]);
        $avg  = $marks->avg();
        $rank = 1;

        $marks->sort()
            ->reverse()
            ->map(function ($mark, $id) use ($avg, &$rank) {
                return [
                    'dev'  => $mark - $avg,
                    'id'   => $id,
                    'mark' => $mark,
                    'rank' => $rank++,
                ];
            })
            ->dump();
        
        /* Illuminate\Support\Collection {
        array:10 [
          3101635921 => [
            "dev" => 55.736
            "id" => 3101635921
            "mark" => 98.0
            "rank" => 1
          ]
          3101625668 => [
            "dev" => 55.736
            "id" => 3101625668
            "mark" => 98.0
            "rank" => 2
          ]
          3913752741 => [
            "dev" => -2.264
            "id" => 3913752741
            "mark" => 40.0
            "rank" => 3
          ]
          3913126364 => [
            "dev" => -6.494
            "id" => 3913126364
            "mark" => 35.77
            "rank" => 4
          ]
          3101372540 => [
            "dev" => -8.794
            "id" => 3101372540
            "mark" => 33.47
            "rank" => 5
          ]
          3913998755 => [
            "dev" => -15.594
            "id" => 3913998755
            "mark" => 26.67
            "rank" => 6
          ]
          3913058204 => [
            "dev" => -16.934
            "id" => 3913058204
            "mark" => 25.33
            "rank" => 7
          ]
          3913861492 => [
            "dev" => -17.064
            "id" => 3913861492
            "mark" => 25.2
            "rank" => 8
          ]
          3913120054 => [
            "dev" => -21.864
            "id" => 3913120054
            "mark" => 20.4
            "rank" => 9
          ]
          3913881854 => [
            "dev" => -22.464
            "id" => 3913881854
            "mark" => 19.8
            "rank" => 10
          ]
        ]
        */
    }

Sorry, I missed the detail about resolving the ties. You'll have to do another pass over the collection to identify and score ties correctly.

InspiredPrynce

@burlresearch thanks alot! It worked perfectly...

InspiredPrynce

@Vilfago thank you as well! I appreciate

InspiredPrynce

@burlresearch there is a slight issue here...

3913261052  10th    51.46
3913936730  9th             51.46

Aren't these two supposed to be 9th then the next one coming becomes 11th?

Vilfago
Vilfago
5 days ago (49,800 XP)

Yes... he told you he didn't do this part...

InspiredPrynce

@Vilfago can you help out? At this point am tired... Please help. ???

Vilfago
Vilfago
4 days ago (49,800 XP)

Did you try my code? I'm tired too

InspiredPrynce

@Vilfago there is an error in this


if($result < $current_score){
        $current_score = $result;
        $current_rank += $number_in_position
        $number_in_position = 1;
        $output[$pin] = [$current_rank, $result];

        ++; //What are you incrementing here?
    }
InspiredPrynce

@Vilfago here is the output


array:1 [▼
  0 => array:2 [▼
    0 => 1
    1 => array:21 [▼
      3913936730 => 28.0
      3913239999 => 21.73
      3913659614 => 22.0
      3913160091 => 19.47
      3913885329 => 29.73
      3913582846 => 30.27
      3913645641 => 15.4
      3913087292 => 23.73
      3913646349 => 14.93
      3913280872 => 21.87
      3913028769 => 13.6
      3913747249 => 26.8
      3913049985 => 22.4
      3913083105 => 25.07
      3913282411 => 40.0
      3913662799 => 39.87
      3913261052 => 20.67
      3913865578 => 9.2
      3913062432 => 17.73
      3913395866 => 35.6
      3913059859 => 34.0
    ]
  ]
]

Vilfago
Vilfago
3 days ago (49,800 XP)
$array_results = [3101625668 => 98.0, 3101635921 => 98.0, 3913126364 => 35.77, 3913058204 => 25.33, 3101372540 => 33.47, 3913752741 => 40.0, 3913120054 => 20.4, 3913998755 => 26.67, 3913861492 => 25.2, 3913881854 => 19.8,];
        
        $results = collect($array_results);

        $results_sorted = $results->sort()->reverse();

        $current_rank = 1;
        $number_in_position = 0;

        $max_score = 100;
        $current_score = $max_score;

        foreach($results_sorted as $pin => $result)
        {
                if($result < $current_score ){
                        $current_score = $result;
                        $current_rank += $number_in_position;
                        $number_in_position = 1;
                        $output[$pin] = [$current_rank, $result];
                }else{ //same score as the previous
                        $number_in_position++;
                        $output[$pin] = [$current_rank, $result];
                }
        }

        dd($output);

Please sign in or create an account to participate in this conversation.