2

I need to group data from my 2d array by one column and sum another column value in the respective groups.

In my data, commas are used as the decimal place character -- these are float values.

Input:

[
    [18, '1,07'];
    [ 8, '0,44'],
    [ 8, '0,67'],
    [18, '0,55'],
    [18, '0,19'],
    [ 8, '0,48'],
    [18, '2,59'],
    [ 8, '0,15'],
    [18, '12,97'],
]

Desired result:

[
    18 => '17,37',
     8 =>  '1,74',
]
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
  • Maybe you could store your VAT prices in a database table too and perform a `SELECT` over that table too. Now yuo can use SQL's sorting and grouping feature. (Also: if 18% = 136,26 how can 8% = 16,90?) – feeela Jul 24 '12 at 14:50
  • Canonical to reduce a 2d array via "group&sum" to an associative array: [Group array data on one column and sum data from another column to form a flat associative array](https://stackoverflow.com/q/3286749/2943403) – mickmackusa Apr 16 '23 at 04:22

3 Answers3

2

Try something like this:

<?php

$data = Array ( 
    Array ( 0 => '18', 1 => '1,07' ),
    Array ( 0 => '8', 1 => '0,44' ),
    Array ( 0 => '8', 1 => '0,67' ),
    Array ( 0 => '18', 1 => '0,55' ), 
    Array ( 0 => '18', 1 => '0,19' ),
    Array ( 0 => '8', 1 => '0,48' ),
    Array ( 0 => '18', 1 => '2,59' ),
    Array ( 0 => '8', 1 => '0,15' ),
    Array ( 0 => '18', 1 => '12,97' ) 
);

// predefine array
$data_summ = array();
foreach ( $data as $value ) {
    $data_summ[ $value[0] ] = 0;
}

foreach ( $data as $list ) {
    $number = str_replace( ",", ".", $list[1] ) * 1;
    $data_summ[ $list[0] ] += (float)$number;
}

?>

Output of $data_summ:

Array
(
    [8] => 1.74
    [18] => 17.37
)

If I understand you correctly.

Peon
  • 7,902
  • 7
  • 59
  • 100
  • You defined a predefine array. But we don't know the values 8 or 18 or 1. Because it depends on product which is on the list. –  Jul 24 '12 at 18:25
  • Edited the code so the array is predefined even if you don't know the values. The 0 starting values are needed to put `float` values in it afterwards. – Peon Jul 25 '12 at 06:27
0
<?php

function multiplyArray($array) {
    $result = array();

    foreach ($array as $value) {
        $result[] = array_product(array_map('floatval', str_replace(',', '.', $value)));
    }

    return $result;
}

$array = array(
    0 => array(0 => '18', 1 => '1,07'),
    1 => array(0 => '8', 1 => '0,44'),
    2 => array(0 => '8', 1 => '0,67'),
    3 => array(0 => '18', 1 => '0,55'),
    4 => array(0 => '18', 1 => '0,19'),
    5 => array(0 => '8', 1 => '0,48'),
    6 => array(0 => '18', 1 => '2,59'),
    7 => array(0 => '8', 1 => '0,15'),
    7 => array(0 => '18', 1 => '12,97'),
);

// Outputs
var_dump($array);
var_dump(multiplyArray($array));
var_dump(array_sum(multiplyArray($array)));
FabianoLothor
  • 2,752
  • 4
  • 25
  • 39
0

Be careful! Last time I dealt with VAT the rules were very strict about calculating VAT on each line item in an invoice, then adding up the total VAT.

Her Majesties Customs and Excise do not accept totaling up the line items and then calculating the VAT on the total. There are two reasons for this:-

  • Plain Greed -- mostly the rounding errors will fall in excise mans favour.
  • Practicality -- Often single line items will be missing from a shipment, rejected or returned -- its much easier to work out the VAT to be credited if it was calculated for each invoice line in the first place.
James Anderson
  • 27,109
  • 7
  • 50
  • 78