Tuesday 29 December 2015

A PHP function to sum values in associative arrays


For a new project, I needed to combine two or more associative arrays and sum the values of any keys that exist in common. I was a little surprised to find that there wasn’t a built-in function to do this in PHP. So I wrote my own. It can accept any number of arrays as arguments, and goes through each array one key at a time, comparing the keys to those in an output array. Where the keys match, the values are summed. If the key does not exist in the output array, it’s appended to it.


The function returns an array that contains all of the unique keys in the input arrays.
<?php
function array_mesh() {
// Combine multiple associative arrays and sum the values for any common keys
// The function can accept any number of arrays as arguments
// The values must be numeric or the summed value will be 0

// Get the number of arguments being passed
$numargs = func_num_args();

// Save the arguments to an array
$arg_list = func_get_args();

// Create an array to hold the combined data
$out = array();

// Loop through each of the arguments
for ($i = 0; $i < $numargs; $i++) {
$in = $arg_list[$i]; // This will be equal to each array passed as an argument

// Loop through each of the arrays passed as arguments
foreach($in as $key => $value) {
// If the same key exists in the $out array
if(array_key_exists($key, $out)) {
// Sum the values of the common key
$sum = $in[$key] + $out[$key];
// Add the key => value pair to array $out
$out[$key] = $sum;
}else{
// Add to $out any key => value pairs in the $in array that did not have a match in $out
$out[$key] = $in[$key];
}
}
}

return $out;
}
$a = array('abc' => '100.000', 'def' => '50', 'ghi' => '25', 'xyz' => '10');
$b = array('abc' => '100.333', 'def' => '75', 'ghi' => '50', 'jkl' => '25');
$c = array('abc' => '100.111', 'def' => '75', 'ghi' => '50', 'uvw' => '5');

echo "<pre>";
print_r(array_mesh($a, $b, $c));
echo "</pre>";
?>
OUTPUT:
Array
(
    [abc] => 300.444
    [def] => 200
    [ghi] => 125
    [xyz] => 10
    [jkl] => 25
    [uvw] => 5
)

Wednesday 2 December 2015

PHP array_insert_after() & array_insert_before()

I need to insert a key/value at a certain position in an associative array. It seems like a common issue. I was surprised to discover there wasn't a straightforward answer. Here is the method I created. If you know of a more efficient method, please let me know in the comments.
/*
 * Inserts a new key/value before the key in the array.
 *
 * @param $key
 *   The key to insert before.
 * @param $array
 *   An array to insert in to.
 * @param $new_key
 *   The key to insert.
 * @param $new_value
 *   An value to insert.
 *
 * @return
 *   The new array if the key exists, FALSE otherwise.
 *
 * @see array_insert_after()
 */
function array_insert_before($key, array &$array, $new_key, $new_value) {
  if (array_key_exists($key, $array)) {
    $new = array();
    foreach ($array as $k => $value) {
      if ($k === $key) {
        $new[$new_key] = $new_value;
      }
      $new[$k] = $value;
    }
    return $new;
  }
  return FALSE;
}
 
/*
 * Inserts a new key/value after the key in the array.
 *
 * @param $key
 *   The key to insert after.
 * @param $array
 *   An array to insert in to.
 * @param $new_key
 *   The key to insert.
 * @param $new_value
 *   An value to insert.
 *
 * @return
 *   The new array if the key exists, FALSE otherwise.
 *
 * @see array_insert_before()
 */
function array_insert_after($key, array &$array, $new_key, $new_value) {
  if (array_key_exists($key, $array)) {
    $new = array();
    foreach ($array as $k => $value) {
      $new[$k] = $value;
      if ($k === $key) {
        $new[$new_key] = $new_value;
      }
    }
    return $new;
  }
  return FALSE;
}