简体   繁体   中英

How to subtract all column values in multi-dimensional array in Php?

How can I subtract all the columns values? My array is like

Array
(
    [0] => Array
        (
            [id] => 1
            [web_traffic] => 442
            [form_users] => 131
            [date] => 20181004
        )

    [1] => Array
        (
            [id] => 2
            [web_traffic] => 102
            [form_users] => 15
            [date] => 20181003
        )
    [2] => Array
        (
            [id] => 3
            [web_traffic] => 387
            [form_users] => 97
            [date] => 20181002
        )
)

I need to subtract the each column(except date & id) and get the result based on date(Ascending order). For example 20181004 means 4th October 2018. My output should like the below

Array
(
    [web_traffic] => -152
    [form_users] => -49
)

My code took reference from How to sum all column values in multi-dimensional array?

foreach ($data as $value) {
        unset($value[ 'id' ]);
        $time = date('Ymd', strtotime($value[ 'date' ]));
        if (in_array($time, $dates)) {
            $value[ 'date' ] = $time;
            foreach ($value as $key => $secondValue) {
                if ( !isset($output[ $key ])) {
                    $output[ $key ] = 0;
                }
                $output[ $key ] -= $secondValue;
            }
        }
    }

Use PHP array_reduce() and array_column() like this:

$initial_array = array(array('id'           => 1,
                     'web_traffic'  => 442,
                     'form_users'   => 131,
                     'date'         => 20181004),
               array('id'           => 2,
                     'web_traffic'  => 102,
                     'form_users'   => 15,
                     'date'         => 20181003),
               array('id'           => 3,
                     'web_traffic'  => 387,
                     'form_users'   => 97,
                     'date'         => 20181002));

function sum($carry, $item)
    {
        $carry -= $item;
        return $carry;
    }

$web_traffic  = array_column($initial_array, "web_traffic");
$form_users = array_column($initial_array, "form_users");
$date = array_column($initial_array, "date");


array_multisort($date, SORT_ASC, $form_users, SORT_DESC,  $initial_array);


$result_array = Array(
            "web_traffic" => array_reduce(array_column($initial_array, "web_traffic"), "sum",2*$initial_array[0]['web_traffic']),
            "form_users" => array_reduce(array_column($initial_array, "form_users"), "sum",2*$initial_array[0]['form_users'])
        );

print_r($result_array);

I would first sort the array using usort() in example.

Sorting first, because that can be tricky to substract in 1 loop the oldest datas to the newers one.

Separating intentions provide a cleaner code, easier to maintain.

The dates don't need to be converted into a date . The string is well formatted and can be used as is in a comparison and a sort. "20170101" < "20180101" , "20180101" < "20181001" and "20181002" < "20181004"

When done, I'll save the first values as initial values to be used in substract.

Then, loop the sorted array and substract the 'web_traffic' and 'form_users' to the initial values.

$datas = array(array('id'           => 1,
                     'web_traffic'  => 442,
                     'form_users'   => 131,
                     'date'         => 20181004),
               array('id'           => 2,
                     'web_traffic'  => 102,
                     'form_users'   => 15,
                     'date'         => 20181003),
               array('id'           => 3,
                     'web_traffic'  => 387,
                     'form_users'   => 97,
                     'date'         => 20181002));

//If needed, you can backup the original array, because usort() will modify it.
$backUpDatas = $datas;

//Sort
usort($datas, function ($arr1, $arr2)
{
    if (isset($arr1['date']) && isset($arr2['date']))
    {
        if ($arr1['date'] == $arr2['date'])
            return (0);
        return (($arr1['id'] > $arr2['id']) ? (-1) : (1));
    }
});

//Initial values
$finalValues['web_traffic'] = $datas[0]['web_traffic'];
$finalValues['form_users'] = $datas[0]['form_users'];

//Substract
foreach ($datas as $key => $value)
{
    if ($key > 0)
    {
        if (isset($value['web_traffic']))
            $finalValues['web_traffic'] -= $value['web_traffic'];
        if (isset($value['form_users']))
            $finalValues['form_users'] -= $value['form_users'];
    }
}

var_dump($finalValues);

Output :

array (size=2)
  'web_traffic' => int -157
  'form_users' => int -49

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM