1

I have a php array like this:

[
    ['url_id' => 2191238, 'time_spent' => 41],
    ['url_id' => 2191606, 'time_spent' => 215],
    ['url_id' => 2191606, 'time_spent' => 25]
]

How to get the SUM of time_spent based on group by url_id (using array_count_values?)?

mickmackusa
  • 43,625
  • 12
  • 83
  • 136
vishnu
  • 495
  • 4
  • 12
  • 26
  • 2
    After going through some of your recent questions, I don't think many of them contain the "right" answer because *you are doing an unfortunately poor job of explaining what you're trying to do*. Please, please, *please* try to explain exactly what outcome you're trying to achieve, including *sample output*. That will help people give you the right answer. – Charles Mar 11 '11 at 05:58

3 Answers3

10

Let's pretend that $array contains our data. We will go through the array and continually add the time_spent to another array keyed by url_id.

$ts_by_url = array();
foreach($array as $data) {
    if(!array_key_exists($data['url_id'], $ts_by_url))
        $ts_by_url[ $data['url_id'] ] = 0;
    $ts_by_url[ $data['url_id'] ] += $data['time_spent'];
}

$ts_by_url should now contain:

2191238 => 41
2191606 => 240 // == 215 + 25
Charles
  • 50,943
  • 13
  • 104
  • 142
0

The OP posted an interesting problem, but the suggestion of using array_count_values() was not applicable; the function does not sum array values but counts their frequency. The answer of @marcocassisa works but is insufficient because of the unfortunate emission of E_NOTICES, albeit unrelated to any math issue. (An undefined variable is unset and thus of NULL value, but in a math context it will temporarily be coerced into a value of zero.) Modern PHP discourages the use of undefined variables by intentionally raising notices when code utilizes them, with one exception starting with PHP 5.1: a statement consisting of only an undefined variable; see here.

To rectify the aforementioned solution, one might use two foreach loops, one to set the index keys and initialize the array elements while the other would perform the summing of values, as follows:

<?php

// set keys and initialize
foreach($arr as $data) {
    $its_by_url[ $data["url_id"] ] = 0;
} 

// now can sum values by url id number:
foreach($arr as $data) {
    $its_by_url[ $data["url_id"] ] += $data["time_spent"];
}

see demo.

While satisfactory, this solution lacks elegance. Attempting to combine the two foreach loops into one, will negatively impact the second element, as it gets defined and then needlessly redefined. One could code per the answer of @Charles and create the url id numbered index if it doesn't already exist. Or, you could test to see if it is set, as follows:

<?php
foreach($arr as $data) {
   if ( !isset( $its_by_url[ $data["url_id"] ] ) ) {
             $its_by_url[ $data["url_id"] ] = 0;
   }
   $its_by_url[ $data["url_id"] ] += $data["time_spent"]; 
}

see demo

Note: if an array element were defined as null, then isset() would return false while array_key_exists() would return true. Per, Ilia Alshanetsky

... if your application does not need to distinguish between an array key that does not exist and one whose value happens to be NULL you should use isset() because it happens to be a little faster.

slevy1
  • 3,797
  • 2
  • 27
  • 33
-1

Why not a simpler

$ts_by_url = array();
foreach($array as $data) {
    $ts_by_url[ $data['url_id'] ] += $data['time_spent'];
}
marcocassisa
  • 372
  • 3
  • 14
  • 5
    When PHP has error reporting turned all the way up, as it should always have, this code will generate notices as PHP tries to perform math on array indexes that don't exist yet. If you're going to copy-paste someone else's answer, don't make it *worse* when doing so. – Charles Feb 05 '13 at 17:19