PluginProbe
Catch Gallery / 1.2
Catch Gallery v1.2
trunk 1.0 1.0.1 1.1 1.2 1.3 1.4 1.5 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 All 27 releases
catch-gallery / math / class-constrained-array-rounding.php

class-constrained-array-rounding.php in Catch Gallery 1.2, at math/class-constrained-array-rounding.php

77 lines 2.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Lets you round the numeric elements of an array to integers while preserving their sum.
5 *
6 * Usage:
7 *
8 * Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $bound_array )
9 * if a specific sum doesn't need to be specified for the bound array
10 *
11 * Jetpack_Constrained_Array_Rounding::get_rounded_constrained_array( $bound_array, $sum )
12 * If the sum of $bound_array must equal $sum after rounding.
13 *
14 * If $sum is less than the sum of the floor of the elements of the array, the class defaults to using the sum of the array elements.
15 */
16 if( ! class_exists( 'Catch_Gallery_Constrained_Array_Rounding' ) ) :
17 class Catch_Gallery_Constrained_Array_Rounding {
18 public static function get_rounded_constrained_array( $bound_array, $sum = false ) {
19 // Convert associative arrays before working with them and convert them back before returning the values
20 $keys = array_keys( $bound_array );
21 $bound_array = array_values( $bound_array );
22
23 $bound_array_int = self::get_int_floor_array( $bound_array );
24
25 $lower_sum = array_sum( wp_list_pluck( $bound_array_int, 'floor' ) );
26 if ( ! $sum || ( $sum < $lower_sum ) ) {
27 // If value of sum is not supplied or is invalid, calculate the sum that the returned array is constrained to match
28 $sum = array_sum( $bound_array );
29 }
30 $diff_sum = $sum - $lower_sum;
31
32 self::adjust_constrained_array( $bound_array_int, $diff_sum );
33
34 $bound_array_fin = wp_list_pluck( $bound_array_int, 'floor' );
35 return array_combine( $keys, $bound_array_fin );
36 }
37
38 private static function get_int_floor_array( $bound_array ) {
39 $bound_array_int_floor = array();
40 foreach ( $bound_array as $i => $value ){
41 $bound_array_int_floor[$i] = array(
42 'floor' => (int) floor( $value ),
43 'fraction' => $value - floor( $value ),
44 'index' => $i,
45 );
46 }
47
48 return $bound_array_int_floor;
49 }
50
51 private static function adjust_constrained_array( &$bound_array_int, $adjustment ) {
52 usort( $bound_array_int, array( 'self', 'cmp_desc_fraction' ) );
53
54 $start = 0;
55 $end = $adjustment - 1;
56 $length = count( $bound_array_int );
57
58 for ( $i = $start; $i <= $end; $i++ ) {
59 $bound_array_int[ $i % $length ]['floor']++;
60 }
61
62 usort( $bound_array_int, array( 'self', 'cmp_asc_index' ) );
63 }
64
65 private static function cmp_desc_fraction( $a, $b ) {
66 if ( $a['fraction'] == $b['fraction'] )
67 return 0;
68 return $a['fraction'] > $b['fraction'] ? -1 : 1;
69 }
70
71 private static function cmp_asc_index( $a, $b ) {
72 if ( $a['index'] == $b['index'] )
73 return 0;
74 return $a['index'] < $b['index'] ? -1 : 1;
75 }
76 }
77 endif;