-2

I've build quite complicated array that contains other arrays with user mails and 'coins' values. I need to remove and count duplicated mails and merge 'coins' values.

Array (
    [0] => Array ( [mail] => mail1@gmail.com [coins] => 25000.00 ) 
    [1] => Array ( [mail] => mail2@gmail.com [coins] => 500000.00 ) 
    [2] => Array ( [mail] => mail1@gmail.com [coins] => 10000.00 ) 
    [3] => Array ( [mail] => mail2@gmail.com [coins] => 10000.00 )
    [4] => Array ( [mail] => mail3@gmail.com [coins] => 20000.00 )
) 

So the output would look like:

mail1@gmail.com (2), 35000.00 coins
mail2@gmail.com (2), 510000.00 coins
mail3@gmail.com (1), 20000.00 coins

Thank you so much!

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Muq
  • 19
  • 5
  • Since this question doesn't show any research effort, I taken the appropriate course of action and downvoted this question. – mickmackusa May 06 '20 at 12:04
  • 1
    SO is a Q&A site, not a code factory or "get your homework done". Please try it yourself first and then ask if you got stuck with an error. – Banana May 07 '20 at 09:28

2 Answers2

1
$grouped = [];
foreach ($array as $item) {
    $email = $item['mail'];
    if (empty($grouped[$email])) {
        $grouped[$email] = ['count' => 0, 'sum' => 0];
    }

    $grouped[$email]['count']++;
    $grouped[$email]['sum'] += $item['coins'];
}

foreach ($grouped as $email => $data) {
    echo $email . '(' . $data['count'] . ') ' . $data['sum'] . ' coins';
}
Kavacky
  • 48
  • 5
u_mulder
  • 54,101
  • 5
  • 48
  • 64
0
  1. Group the data by assigning temporary associative keys (mail values) to a new result array.
  2. While iterating, determine if you are processing the first occurrence of a mail value or not by calling isset() on the mail key of the result array.
  3. If this is the first instance of the mail, set all of the values in the subarray.
  4. If this is not the first instance of the mail value, adjust the pre-existing subarray.
  5. After looping, use printf() to concisely format your data as desired.

In case the float output syntax is unfamiliar, read this.

Code: (Demo)

$array = [
    ['mail' => 'mail1@example.com', 'coins' => '25000.00'],
    ['mail' => 'mail2@example.com', 'coins' => '500000.00'],
    ['mail' => 'mail1@example.com', 'coins' => '10000.00'],
    ['mail' => 'mail2@example.com', 'coins' => '10000.00'],
    ['mail' => 'mail3@example.com', 'coins' => '20000.00'],
];

$result = [];
foreach ($array as ['mail' => $mail, 'coins' => $coins]) {
    if (!isset($result[$mail])) {
        $result[$mail] = [1, $coins];  // declare the data for the first instance of mail
    } else {
        ++$result[$mail][0];          // increment the running count
        $result[$mail][1] += $coins;  // add coins to running total
    }
}

foreach ($result as $mail => $row) {
    printf("%s (%d), %.2f coins\n", $mail, ...$row);  // unpack the row with the splat operator (...)
}

Output:

mail1@example.com (2), 35000.00 coins
mail2@example.com (2), 510000.00 coins
mail3@example.com (1), 20000.00 coins
mickmackusa
  • 43,625
  • 12
  • 83
  • 136