0

I have 2 arrays - Dealerships and Scores:

Dealerships

Array(
    [0] => Test Dealership 2
    [1] => Test Dealership
    [2] => Test Dealership
    [3] => Test Dealership 3
    [4] => Test Dealership
)

Scores

Array(
    [0] => 0
    [1] => 427
    [2] => 266
    [3] => 375
    [4] => 180
)

All I am trying to do is create a leaderboard that looks like this:

It needs to combine the scores for matching dealerships.


Dealership Leaderboard

1. Test Dealership - 873
2. Test Dealership 3 - 375
3. Test Dealership 2 - 0


I have mapped the arrays to create this:

Array
(
    [0] => Array
        (
            [0] => Test Dealership 2
            [1] => 0
        )

    [1] => Array
        (
            [0] => Test Dealership
            [1] => 427
        )

    [2] => Array
        (
            [0] => Test Dealership
            [1] => 266
        )

    [3] => Array
        (
            [0] => Test Dealership 3
            [1] => 375
        )

    [4] => Array
        (
            [0] => Test Dealership
            [1] => 180
        )

)

But I'm drawing a blank on how to get to the next stage.

Lee Harris
  • 13
  • 4
  • Where does 873 comes from in 1. Test Dealership - 873. Your question is not clear. What do you want to do.? – Tufail Ahmad Jun 11 '20 at 04:57
  • @TufailAhmad Apologies, thought that would be obvious. They are the 'combined' scores in the array. So the total points for "Test Dealership" is 873. That's 427+266+180. – Lee Harris Jun 11 '20 at 05:18

2 Answers2

0

If your data comes from a database, you could handle this problem in the select-query.

But given your two arrays, simply create a new array where the key is the name so you can check for it

$array1=['Test Dealership 2','Test Dealership',...];
$array2=[0,427,...];

$new_array=[];

foreach($array1 as $key => $value){
   //test if KEY (= name) exists in the new array
   //if so, add the value
   if( isset( $new_array[$key] ) ){
      $new_array[$key] += $array2[$key];
      continue;
      }
   //else create a new entry in the new array
   $new_array[ $key] = $array2[$key];
   }

You'll end up with an array like this:

 [
   'Test Dealership 2' => 0 ,
   'Test Dealership' => 873 ,
   'Test Dealership 3' => 375
]

If you want the result sorted for a ranking list:

   arsort($new_array);

To get the strings you want, loop the new_array:

$rank=1;
foreach( $new_array as $key => $value ){
   echo $rank.' '.$key.' - '.$value;
   ++$rank;
   }
Michel
  • 4,076
  • 4
  • 34
  • 52
0

You're probably looking for a function like this:

function reduce_total_scores($input) {
        $output = array_reduce($input, function ($carry, array $current) {
                if (!isset($carry[$current[0]])) $carry[$current[0]] = 0;
                $carry[$current[0]] += $current[1];
                return $carry;
        }, []);
        arsort($output);
        return $output;
}

To show it in action:

<?php

$dealerships = [
        'Test Dealership 2',
        'Test Dealership',
        'Test Dealership',
        'Test Dealership 3',
        'Test Dealership',
];

$scores = [
        0,
        427,
        266,
        375,
        180,
];

/**
 * Just a function to create the combined array as the poster did.
 */
function join_array_values(...$arrs) {
        $result = [];
        $l = array_reduce($arrs, function ($carry, array $current) {
                $l = sizeof($current);
                return ($carry >= $l) ? $carry : $l;
        }, 0);
        foreach ($arrs as $i => $arr) {
                $arr = array_values($arr); // only take values
                for ($j=0; $j<$l; $j++) {
                        $result[$j][$i] = $arr[$j] ?? null;
                }
        }
        return $result;
}

/**
 * Reduce the totals of different dealerships
 */
function reduce_total_scores($input) {
        $output = array_reduce($input, function ($carry, array $current) {
                if (!isset($carry[$current[0]])) $carry[$current[0]] = 0;
                $carry[$current[0]] += $current[1];
                return $carry;
        }, []);
        arsort($output);
        return $output;
}

$input = join_array_values($dealerships, $scores);

echo "input\n------\n";
print_r($input);

echo "\nresult\n------\n";
print_r(reduce_total_scores($input));

Run Result:

input
------
Array
(
    [0] => Array
        (
            [0] => Test Dealership 2
            [1] => 0
        )

    [1] => Array
        (
            [0] => Test Dealership
            [1] => 427
        )

    [2] => Array
        (
            [0] => Test Dealership
            [1] => 266
        )

    [3] => Array
        (
            [0] => Test Dealership 3
            [1] => 375
        )

    [4] => Array
        (
            [0] => Test Dealership
            [1] => 180
        )

)

output
------
Array
(
    [Test Dealership] => 873
    [Test Dealership 3] => 375
    [Test Dealership 2] => 0
)

Should be easy to fashion an output from the assoc array produced by reduce_total_scores().

Koala Yeung
  • 7,475
  • 3
  • 30
  • 50