Skip to content

Instantly share code, notes, and snippets.

@jtsternberg
Last active December 28, 2017 23:48
Show Gist options
  • Save jtsternberg/f9f097170ff95769afd440b48a6e2470 to your computer and use it in GitHub Desktop.
Save jtsternberg/f9f097170ff95769afd440b48a6e2470 to your computer and use it in GitHub Desktop.
Recursively calculate totals from an array of arrays (with matching keys, etc)
<?php
/**
* Calculate totals from a nested array. Handles nested recursion.
* Uses first nested array as the "pattern" for building the totals array.
*
* @param array $to_count The multi-dimensional array to calculate the totals for.
*
* @return array The array of totals.
*/
function calculate_array_totals( $to_count ) {
return _calculate_array_totals( $to_count[ key( $to_count ) ], $to_count );
}
/**
* Calculate totals from a nested array. Handles nested recursion.
* Uses first parameter as the "pattern" for building the totals array.
*
* @param array $totals The pattern of the totals. Should match the keys you
* want to calculate the totals for.
* @param array $to_count The multi-dimensional array to calculate the totals for.
*
* @return array The $totals array with calculated totals.
*/
function _calculate_array_totals( $totals, $to_count ) {
foreach ( $totals as $key => $value ) {
if ( is_array( $value ) ) {
// Handle recursion.
$_counts = array();
foreach ( $to_count as $parent_key => $array_counts ) {
if ( isset( $array_counts[ $key ] ) ) {
$_counts[] = $array_counts[ $key ];
}
}
$totals[ $key ] = _calculate_array_totals( $value, $_counts );
} else {
$value = 0;
foreach ( $to_count as $parent_key => $array_counts ) {
if ( isset( $array_counts[ $key ] ) && is_numeric( $array_counts[ $key ] ) ) {
$value += $array_counts[ $key ];
}
}
// If we stumbled on a non-numeric value, remove this.
if ( ! $value && ! is_numeric( $totals[ $key ] ) ) {
unset( $totals[ $key ] );
} else {
$totals[ $key ] = $value;
}
}
}
return $totals;
}
$to_count = array(
array(
'Facebook' => array(
'do_share' => true, // Will be ignored/discarded from totals.
'share_count' => 34,
'like_count' => 0,
'comment_count' => 10,
'total_count' => 64,
'extra-nested' => array(
'share_count' => 999,
'like_count' => 1,
'comment_count' => 10,
'total_count' => 64,
),
),
'Twitter' => 12,
'Pinterest' => 177,
'LinkedIn' => 0,
'GooglePlusOne' => 0,
'StumbleUpon' => 0,
),
array(
'Facebook' => array(
'do_share' => false, // Will be ignored/discarded from totals.
'share_count' => 116,
'like_count' => 0,
'comment_count' => 54,
'total_count' => 296,
'extra-nested' => array(
'share_count' => 116,
'like_count' => 0,
'comment_count' => 54,
'total_count' => 296,
),
),
'Twitter' => 0,
'Pinterest' => 1878,
'LinkedIn' => 0,
'GooglePlusOne' => 0,
'StumbleUpon' => 0,
),
array(
'Facebook' => array(
'do_share' => null, // Will be ignored/discarded from totals.
'share_count' => 1,
'like_count' => 2,
'comment_count' => 3,
'total_count' => 4,
'extra-nested' => array(
'share_count' => 116,
'like_count' => 0,
'comment_count' => 54,
'total_count' => 296,
),
),
'Twitter' => 0,
'Pinterest' => 1,
'LinkedIn' => 2,
'GooglePlusOne' => 3,
'StumbleUpon' => 4,
),
);
// $totals = calculate_array_totals( $to_count );
/*
Generates: Array
(
[Facebook] => Array
(
[share_count] => 151
[like_count] => 2
[comment_count] => 67
[total_count] => 364
[extra-nested] => Array
(
[share_count] => 1231
[like_count] => 1
[comment_count] => 118
[total_count] => 656
)
)
[Twitter] => 12
[Pinterest] => 2056
[LinkedIn] => 2
[GooglePlusOne] => 3
[StumbleUpon] => 4
)
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment