PHP Multidemensional Array if two items match then add together a corresponding item and return new array

StackOverflow https://stackoverflow.com/questions/23543312

Question

I have an array that returns as follows:

array(5) {
  [0]=>
  array(2) {
    ["order_id"]=>
    string(3) "257"
    ["price"]=>
    string(7) "20.3600"
  }
  [1]=>
  array(2) {
    ["order_id"]=>
    string(3) "256"
    ["price"]=>
    string(7) "20.5500"
  }
  [2]=>
  array(2) {
    ["order_id"]=>
    string(3) "255"
    ["price"]=>
    string(7) "30.0000"
  }
  [3]=>
  array(2) {
    ["order_id"]=>
    string(3) "255"
    ["price"]=>
    string(7) "22.3800"
  }
  [4]=>
  array(2) {
    ["order_id"]=>
    string(3) "254"
    ["price"]=>
    string(7) "20.6300"
  }
}

What I'd like to end up with is:

array(4) {
  [0]=>
  array(2) {
    ["order_id"]=>
    string(3) "257"
    ["price"]=>
    string(7) "20.3600"
  }
  [1]=>
  array(2) {
    ["order_id"]=>
    string(3) "256"
    ["price"]=>
    string(7) "20.5500"
  }
  [2]=>
  array(2) {
    ["order_id"]=>
    string(3) "255"
    ["price"]=>
    string(7) "52.3800"
  }
  [3]=>
  array(2) {
    ["order_id"]=>
    string(3) "254"
    ["price"]=>
    string(7) "20.6300"
  }
}

The logic being if the array contains matching order numbers then add the prices together of those order numbers and return a new array with unique order ids and added prices if and one single order id.

So in the example since there are two order_id's that are the same (255) that have 22.38 and 30 as the price then the new array should have only one item for order_id 255 and an associated price of 52.38.

Currently I've gotten as far as being able to return only unique IDs using this function:

        function super_unique($array,$key) {
            $temp_array = array();
            foreach ($array as &$v) {
                if (!isset($temp_array[$v[$key]]))
                    $temp_array[$v[$key]] =& $v;
            }
            $array = array_values($temp_array);

            return $array;
        }

and I've tried something like this in order to add the prices together but I'm getting operand errors:

       function super_unique_addition($array,$key,$total) {
        $temp_array = array();
        foreach ($array as &$v) {
            if (!isset($temp_array[$v[$key]])) {
                $temp_array[$v[$key]] =& $v;
                $temp_array[$v[$total]] += $v;
            }
        }
        $array = array_values($temp_array);

        return $array;
    }

Greatly appreciate any insight on this! Thanks in advance for any help!

Was it helpful?

Solution

You could just use plain ol' foreach on this one, and build it on a new array. Consider this example:

$values = array(
    0 => array('order_id' => '257', 'price' => '20.3600'),
    1 => array('order_id' => '256', 'price' => '20.5500'),
    2 => array('order_id' => '255', 'price' => '30.0000'),
    3 => array('order_id' => '255', 'price' => '22.3800'),
4 => array('order_id' => '254', 'price' => '20.6300'),
);

$new_values = array();
foreach($values as $key => $value) {
    $new_values[$value['order_id']]['order_id'] = $value['order_id'];
    // initialize price
    if(!isset($new_values[$value['order_id']]['price'])) $new_values[$value['order_id']]['price'] = 0;
    $new_values[$value['order_id']]['price'] += $value['price']; 
}

$new_values = array_values($new_values); // reindex the array
print_r($new_values); // print

OTHER TIPS

Just array_reduce your stuff in order to group by order price:

$newArray = array_reduce($array, function($memo, $item){

  $memo[$item['order_id']] += $item['price'];

}, [])

EDIT: note that you may GROUP/SUM your data at query time better.

function _new_array()
{
   $temp1 = [];

   foreach (func_get_args() as $arg)
   {
       if (!is_array($arg)) continue;

       foreach ($arg as $val)
       {
           if (isset($temp1[$val['order_id']]))
              $temp1[$val['order_id']] += $val['price'];

           else
              $temp1[$val['order_id']] = $val['price'];
       }
   }

   $result = [];

   foreach ($temp1 as $k => $v) $result[] = ['order_id' => $k, 'price' => $v];

   return $result;
}

$result = _new_array($array1, $array2, $array3);

Possibly:

<?php

$your_array = array( ... );

# Loop array
for( $i=0; $i<count($your_array); $i++ )
{
    # Loop array again for each item in it
    for( $j=0; $j<count($your_array; $j++) )
    {
        # If the order IDs are the same, add the prices and make the $j array values null
        if( $your_array[$i]["order_id"] === $your_array[$j]["order_id"] )
        {
            $your_array[$i]["price"] += $your_array[$j]["price"];

            $your_array[$j]["order_id"] = null;
            $your_array[$j]["price"]    = null;
        }
    }
}

# array_filter should remove the null values
$final_array = array_filter($your_array);

?>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top