4

I'm looping through the result sets of two stored procedures, getting results within one stored procedures based on fields within the other.

The two arrays containing the results sets are $customers and $subcustomers.

foreach($customers as $customer)
{
      foreach($subcustomers as $subcustomer)
      {
            if($subcustomer['parent'] == $customer['id'])
            {                        
                  if($customer['innumber'] == null && $subcustomer['innumber'] != null)
                  {                       
                      $chartInboundSub['name'] = $customer['name'];
                      $chartInboundSub['label'] = $subcustomer['innumber'];
                      $chartInboundSub['countInbound'] = $customer['count'];
                      $chartInboundSub['minsInbound'] = ceil($customer['duration'] / 60);
                      $chartInboundSub['customerid'] = $customer['id'];

                      array_push($out['chartInbound'], $chartInboundSub);
                  }
            }
       }
}

The current output of print_r($out['chartInbound']) is the below:

Array
(
    [0] => Array
        (
            [countInbound] => 426
            [minsInbound] => 340
            [name] => Telekomm
            [label] => 01-02
            [customerid] => 6
        )

    [1] => Array
        (
            [countInbound] => 1
            [minsInbound] => 2
            [name] => Telekomm
            [label] => 01-02
            [customerid] => 6
        )

    [2] => Array
        (
            [countInbound] => 3
            [minsInbound] => 21
            [name] => Telekomm
            [label] => 080
            [customerid] => 6
        )

    [3] => Array
        (
            [countInbound] => 1920
            [minsInbound] => 15766
            [name] => Telekomm
            [label] => 084
            [customerid] => 6
        )

    [4] => Array
        (
            [countInbound] => 2332
            [minsInbound] => 17521
            [name] => Telekomm
            [label] => 084
            [customerid] => 6
        )
    ...
)

The above results need to be grouped by name, label, customerid with countInbound and minsInbound summed, so :

The desired output should be:

Array
    (
        [0] => Array
            (
                [countInbound] => 427
                [minsInbound] => 342
                [name] => Telekomm
                [label] => 01-02
                [customerid] => 6
            )

        [1] => Array
            (
                [countInbound] => 3
                [minsInbound] => 21
                [name] => Telekomm
                [label] => 080
                [customerid] => 6
            )

        [2] => Array
            (
                [countInbound] => 4252
                [minsInbound] => 33287
                [name] => Telekomm
                [label] => 084
                [customerid] => 6
            )
        ...
    )
3
  • Sorry i don't really get it, you want to sum countInbound and minsInbound when name, label and customerid are the same? Commented Jun 25, 2015 at 13:38
  • @PHPeter: Yes, that is correct Commented Jun 25, 2015 at 14:05
  • Although pieces of data can be gleaned from reverse engineering the input arrays, it is possible to provide an answer however this question Needs Clarity. Specifically, the minimal reproducible example is missing populated $customers and $subcustomers arrays which can be used to generate the desired result. Commented Jan 16, 2024 at 11:47

2 Answers 2

2

I think this should work. I haven't tested the code, so I make no promises.

$map = array();
$i = 0;

foreach($customers as $customer)
{
      foreach($subcustomers as $subcustomer)
      {
            if($subcustomer['parent'] == $customer['id'])
            {                        
                  if($customer['innumber'] == null && $subcustomer['innumber'] != null)
                  {                       

                      $key = $customer['name'] . '/' . $subcustomer['innumber'] . '/' . $customer['id'];

                      if(isset($map[$key])) {
                            $out['chartInbound'][$map[$key]]['countInbound'] += $customer['count'];
                            $out['chartInbound'][$map[$key]]['minsInbound'] += ceil($customer['duration'] / 60);
                      }
                      else {
                          $out['chartInbound'][$i] = array(
                                  'name' => $customer['name'],
                                  'label' => $subcustomer['innumber'],
                                  'countInbound' => $customer['count'],
                                  'minsInbound' => ceil($customer['duration'] / 60),
                                  'customerid' => $customer['id'],
                          );
                          $map[$key] = $i++;
                    }
                  }
            }
       }
}

For every combination of name, label and customerid it creates a string key that has to be unique for that combination. Then it checks if there is already any data for that key (by keeping a separate list of keys and their indexes in $out['chartInbound']). If so it just adds the countInbound and minsInbound. If not it puts the whole $chartInboundSub into $out['chartInbound'].

Please note that this relies on the key being unique. If you for instance allow / in the names that might not be the case.

Sign up to request clarification or add additional context in comments.

Comments

1

Rather than use foreach loops I use the 'iterator' that every PHP array has.

Assuming the array is sorted then a single pass recording the 'current group id' will be sufficient.

I use a 'read ahead' technique that so an'if' test is not needed to find out what to do with with the 'current record'.

working code as 'eval.in'

The code:

/**
 * Output stored in here...
 */
$output = array();

// groupId consists of:   name, label, customerid

// read ahead - we need the current entry of the source array...
$currentEntry = current($source);

while ($currentEntry !== false) { // process the array / file / resultset etc.

    // start of a group... process the first record that every group has...
    $currentGroupId = getGroupId($currentEntry);
    $currentGroupCountInbound = $currentEntry['countInbound'];
    $currentGroupMinsInbound = $currentEntry['minsInbound'];

    // read the next record as we always 'read ahead' after processing a record...
    next($source);
    $currentEntry = current($source);

     while ($currentGroupId == getGroupId($currentEntry)) {
        // same group = total the values...

       $currentGroupCountInbound += $currentEntry['countInbound'];
       $currentGroupMinsInbound += $currentEntry['minsInbound'];

       // next entry in the input array - will end this group if not the same...
       next($source);
       $currentEntry = current($source);
    }

    // end of the current group -- output the information...
    // add it to an array... or whatever...
    $output[] = array('groupid' => $currentGroupId,
                       'countInbound' => $currentGroupCountInbound,
                       'minsInbound' => $currentGroupMinsInbound);
}

// show the output...
echo '<pre>';
print_r($output);
echo '</pre>';
exit;

// ---------------------------------
function getGroupId($entry = array())
{
    if (empty($entry)) {
        return array();
    }

    return array(
        $entry['name'], $entry['label'], $entry['customerid']
    );
}

The output:

Array(
    [0] => Array(
            [groupid] => Array(
                    [0] => Telekomm
                    [1] => 01-02
                    [2] => 6
                )
            [countInbound] => 427
            [minsInbound] => 342
        )

    [1] => Array(
            [groupid] => Array(
                    [0] => Telekomm
                    [1] => 080
                    [2] => 6
                )
            [countInbound] => 3
            [minsInbound] => 21
        )

    [2] => Array(
            [groupid] => Array(
                    [0] => Telekomm
                    [1] => 084
                    [2] => 6
                )
            [countInbound] => 4252
            [minsInbound] => 33287
        )
)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.