PrimuS
PrimuS

Reputation: 2683

Re-Order Array in php foreach

I have an array that looks like this:

Array
(
[0] => Array
    (
        [amount] => 75.00
        [name] => CLIENT1
        [week] => 22
    )

[1] => Array
    (
        [amount] => 945.00
        [name] => CLIENT1
        [week] => 23
    )

[2] => Array
    (
        [amount] => 45.00
        [name] => CLIENT1
        [week] => 24
    )
...

[15] => Array
    (
        [amount] => 45.00
        [name] => CLIENTX
        [week] => 22
    )

[16] => Array
    (
        [amount] => 15.00
        [name] => CLIENTX
        [week] => 22
    )
// HAS NO VALUE IN WEEK 23 BUT TWO IN WEEK 22!!!
[17] => Array
    (
        [amount] => 73.00
        [name] => CLIENTX
        [week] => 24
    )

I need an array that looks like this

Array
(
['weeks'] => Array (22,23,24) //ALL WEEKS FOUND SOMEWHERE
['series'] => Array
           (
           [0] => Array
               (
                 ['name'] => 'CLIENT1'
                 ['data'] => Array (75.00, 945.00, 45.00)
               )
           [1] => Array
               (
                 ['name'] => 'CLIENTX'
                 ['data'] => Array (60.00, 0, 73.00)
               )
          )
)

First try

This is rather a logical problem, not a matter of programming, but I am stuck from looking at it for so long now.

The ['weeks'] => Array (22,23,24) shouldn't be a problem, but the rest really is.

The closest I got so far is this:

$clientArray = array();
$weekAmount = array();
foreach($hours as $hour){
    /* For better readability */
    $client = $hour['name'];
    $amount = $hour['amount'];
    $week = $hour['week'];

    if(!array_key_exists($week, $weekAmount)){
        $weekAmount[$week] = 0;
    }
    $weekAmount[$week] = $amount;
    $clientArray[$client] = $weekAmount;
    ksort($clientArray[$client]); // to order by weeks
}

But this does not add up values from the same week and I need to loop through this again and I don't know how to find the "missing" weeks and set 0 as the according value.

I hope I explained myself clearly, if not I try again.

Upvotes: 0

Views: 52

Answers (1)

roberto06
roberto06

Reputation: 3864

There must be a more efficient way than this, but at least it works :

<?php

$input = array(
    array('amount'  => 75.00,
          'name'    => 'CLIENT1',
          'week'    => 22),
    array('amount'  => 945.00,
          'name'    => 'CLIENT1',
          'week'    => 23),
    array('amount'  => 45.00,
          'name'    => 'CLIENT1',
          'week'    => 24),
    array('amount'  => 45.00,
          'name'    => 'CLIENTX',
          'week'    => 22),
    array('amount'  => 15.00,
          'name'    => 'CLIENTX',
          'week'    => 22),
    array('amount'  => 73.00,
          'name'    => 'CLIENTX',
          'week'    => 24),
);

$weeks = array();
$names = array();
foreach ($input as $v) {
    if (!isset($weeks[$v['week']]))
        $weeks[$v['week']] = array();
    if (!isset($names[$v['name']]))
        $names[$v['name']] = array();
    if (!isset($names[$v['name']][$v['week']]))
        $names[$v['name']][$v['week']] = 0;
    $names[$v['name']][$v['week']] += $v['amount'];
}

$output = array('weeks' => array(), 'series' => array());
foreach ($weeks as $week=>$values) {
    $output['weeks'][] = $week;
}
foreach ($names as $name=>$data) {
    $serie = array();
    $serie['name'] = $name;
    foreach ($weeks as $week=>$values) {
        if (isset($data[$week]))
            $serie['data'][] = $data[$week];
        else
            $serie['data'][] = 0;
    }
    $output['series'][] = $serie;
}

echo '<pre>'; print_r($output);
?>

Returns :

Array
(
    [weeks] => Array
        (
            [0] => 22
            [1] => 23
            [2] => 24
        )
    [series] => Array
        (
            [0] => Array
                (
                    [name] => CLIENT1
                    [data] => Array
                        (
                            [0] => 75
                            [1] => 945
                            [2] => 45
                        )

                )    
            [1] => Array
                (
                    [name] => CLIENTX
                    [data] => Array
                        (
                            [0] => 60
                            [1] => 0
                            [2] => 73
                        )    
                )    
        )    
)

Upvotes: 1

Related Questions