简体   繁体   中英

PHP: calculate array values by array

This may be simple to some of you guys but I'm really dummy in php. All what I need is just to transform a multidimensional array and calculate some of it's sub array values.

  Array
    (
        [0] => Array
            (
                [date] => 2014-10-30
                [mission] => one
                [point] => 10
            )

        [1] => Array
            (
                [date] => 2014-10-31
                [mission] => five
                [point] => 10
            )

        [2] => Array
            (
                [date] => 2014-11-19
                [mission] => one
                [point] => 8
            )

And the output would be like:

 Array
(
    [one] => Array
        (
            [mission] => one
            [point] => 18 // sum all points where [mission] => one
            [count] => 2
            [everage] => 9 // 18/2
        )

    [five] => Array
        (
            [mission] => five
            [point] => 10
            [count] => 1
            [everage] => 10
        )

It is simple to get the sum of [point] values using foreach but troubles begin when I try to get count of arrays with same [mission] value. Thats my code:

foreach($missionsarray as $row) {
  if(!isset($newarray[ $row['mission'] ])) {
       $newarray[ $row['mission'] ] = $row;
       $newarray[ $row['mission'] ]['count'] = count($row['point']);
       continue ;
   }
   $newarray[ $row['mission'] ]['point'] += $row['point'];
}

print_r($newarray);

The argument to count() should be an array, it returns the number of elements in that array. That's not what you want. When you first create a new entry in your results for a mission, you should set count to 1 . Then you just increment it every time you add another point to it.

foreach($missionsarray as $row) {
  if(!isset($newarray[ $row['mission'] ])) {
       $newarray[ $row['mission'] ] = $row;
       $newarray[ $row['mission'] ]['count'] = 1;
       continue ;
   }
   $newarray[ $row['mission'] ]['point'] += $row['point'];
   $newarray[ $row['mission'] ]['count']++;
}

print_r($newarray);

Use this

$newarray[ $row['mission'] ]['point'] += $row['point'];
$newarray[ $row['mission'] ]['count']++;

print_r($newarray);

Update for PHP 5.5

array_column()

$counts = array_count_values(array_flip(array_column($array, 'point')));

First off, I think this line gives you trouble:

$newarray[ $row['mission'] ]['count'] = count($row['point']);

You should set the initial count to 0, as you've seen no records so far:

$newarray[ $row['mission'] ]['count'] = 0;

After you do that, every time you see another record with the same mission, you can add one to the count like this:

$newarray[ $row['mission'] ]['point'] += $row['point'];
$newarray[ $row['mission'] ]['count']++;

After that you should be fine calculating the average.

I think what you're trying to do is the following:

foreach ($missionsarray as $row) {
    $mission = $row['mission'];
    $point   = $row['point'];

    if (! isset($newarray[$mission])) {
        $newarray[$mission] = [
            'mission' => $mission,
            'point'   => 0,
            'count'   => 0,
            'average' => 0
        ];
    }

    $newarray[$mission]['point'] += $point;
    $newarray[$mission]['count']++;

    $newarray[$mission]['average'] =
        $newarray[$mission]['point'] / $newarray[$mission]['count'];
}

I think it might be easier to solve this problem with a for-loop, as follows:

<?php

$arr = array(0 => array("date" => "2014-10-30","mission" => "one","point" => 10),
             1 => array("date" => "2014-10-31","mission" => "five","point" => 10),
             2 => array("date" => "2014-11-19","mission" => "one","point" => 8)
             );

$ototal = 0; // total mission one points
$ftotal = 0; // total mission five points

$ocount = 0; // count for mission one
$fcount = 0; // count for mission five

for ($i=0, $max = count( $arr ); $i < $max; $i++){
    if ($arr[$i]["mission"] == "one"){
        $ototal += $arr[$i]["point"];
        $ocount++;

    }
    else
    if ($arr[$i]["mission"] == "five"){
        $ftotal += $arr[$i]["point"];
        $fcount++;
    }
}

// transform $arr by adding the following elements:
$arr["one"] = array("mission" => "one", "point" => $ototal, "count" => $ocount, "average" => $ototal/ $ocount);
$arr["five"]= array("mission" => "five","point" => $ftotal, "count" => $fcount, "average" => $ftotal/$fcount);

var_dump($arr["one"],$arr["five"]);

live demo here

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