-2

I try to figure out how to handle my array to do "some math" with its values. The array looks similar to this:

Array
(
[0] => Array
    (
        [person1] => 71
        [person2] => 49
        [person3] => 15
    )

[1] => Array
    (
        [person1] => 56
        [person3] => 43
        [person4] => 21
        [person5] => 9
        [person6] => 7
    )

...

)

Each value should be divided by the total amount: The first value should therefore be 71/(71+49+15)=0.526 or 52.6%.

The values should be rounded to 3 decimal places. Can someone provide me with an array_walk (or foreach) function? I just can't figure it out.

The final array should look like this:

Array
(
[0] => Array
    (
        [person1] => 52.6%
        [person2] => 36.3%
        [person3] => 11.1%
    )

[1] => Array
    (
        [person1] => 41.2%
        [person3] => 31.6%
        [person4] => 15.4%
        [person5] => 6.6%
        [person6] => 5.1%
    )

...

)

Thanks!

Felix Bernhard
  • 396
  • 6
  • 24
  • Care to share anything that you have tried? In addition you say "rounded to 3 decimal places" but your example shows one decimal place. Which should it really be? – Jay Blanchard May 05 '14 at 21:49
  • @JayBlanchard: one decimal place in the resulting percentage they want. – AbraCadaver May 05 '14 at 21:51
  • Brilliant! @AbraCadaver ;) – Jay Blanchard May 05 '14 at 21:52
  • yes, one decimal place in the percentage. I tried to use `foreach($array as $k => $v)` in combination with `array_sum()` for the values, but it never worked actually out. I don't know how to access the values of the second dimension and re-calculate them – Felix Bernhard May 05 '14 at 21:56

3 Answers3

4

Assuming $arr is your initial array, and $new_arr will be the new one.

$new_arr = array();
foreach ($arr as $i=>$ar)
    foreach ($ar as $j=>$a)
        $new_arr[$i][$j] = round(($a/array_sum($ar))*100, 1);
Mark Miller
  • 7,442
  • 2
  • 16
  • 22
3

The array_walk() variation:

$data = array(
    array(
        'person1' => 71,
        'person2' => 49,
        'person3' => 15,
    ),
    array(
        'person1' => 56,
        'person3' => 43,
        'person4' => 21,
        'person5' => 9,
        'person6' => 7,
    ),
);

array_walk(
    $data,
    function (&$value) {
        $sum = array_sum($value);
        array_walk(
            $value,
            function (&$value) use ($sum) {
                $value = round($value / $sum, 3) * 100 . '%';
            }
        );
    }
);
var_dump($data);

Note that array_walk() modifies the original array; if you want that to remain unchanged, use array_map() instead

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
1

You can use array_sum() to add up those values, then calculate your ratio/percentage for each and add to a new array:

$output = array();

foreach($array as $key => $current) {
    $total = array_sum($current);
    $output[$key] = array();

    foreach($current as $person => $value) {
        // decimal: round to 3 places
        $output[$key][$person] = round($value / $total, 3); 
        // if you want a percentage, round to another 1 place (as per your example):
        // $output[$key][$person] = round($output[$key][$person] * 100, 1) . '%';
    }
}

Edit: here's a demo

scrowler
  • 24,273
  • 9
  • 60
  • 92