PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | modules/tiled-gallery/math/class-constrained-array-rounding.php +108 -0 16.2-beta → 16.3-beta View file →
@@ -1,0 +1,108 @@
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
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 +class Jetpack_Constrained_Array_Rounding {
17 + /**
18 + * Get the rounded constrained array.
19 + *
20 + * @param array $bound_array - the array we're rounding.
21 + * @param int $sum - the sum of the array.
22 + *
23 + * @return array
24 + */
25 + public static function get_rounded_constrained_array( $bound_array, $sum = false ) {
26 + // Convert associative arrays before working with them and convert them back before returning the values
27 + $keys = array_keys( $bound_array );
28 + $bound_array = array_values( $bound_array );
29 +
30 + $bound_array_int = self::get_int_floor_array( $bound_array );
31 +
32 + $lower_sum = array_sum( wp_list_pluck( $bound_array_int, 'floor' ) );
33 + if ( ! $sum || ( $sum < $lower_sum ) ) {
34 + // If value of sum is not supplied or is invalid, calculate the sum that the returned array is constrained to match
35 + $sum = array_sum( $bound_array );
36 + }
37 + $diff_sum = $sum - $lower_sum;
38 +
39 + self::adjust_constrained_array( $bound_array_int, $diff_sum );
40 +
41 + $bound_array_fin = wp_list_pluck( $bound_array_int, 'floor' );
42 + return array_combine( $keys, $bound_array_fin );
43 + }
44 +
45 + /**
46 + * Get int floor of array values.
47 + *
48 + * @param array $bound_array - the array we're getting floor values for.
49 + *
50 + * @return array
51 + */
52 + private static function get_int_floor_array( $bound_array ) {
53 + $bound_array_int_floor = array();
54 + foreach ( $bound_array as $i => $value ) {
55 + $bound_array_int_floor[ $i ] = array(
56 + 'floor' => (int) floor( $value ),
57 + 'fraction' => $value - floor( $value ),
58 + 'index' => $i,
59 + );
60 + }
61 +
62 + return $bound_array_int_floor;
63 + }
64 +
65 + /**
66 + * Adjust the constrained array.
67 + *
68 + * @param array $bound_array_int - the array we're adjusting.
69 + * @param int $adjustment - how much we're adjusting the array.
70 + */
71 + private static function adjust_constrained_array( &$bound_array_int, $adjustment ) {
72 + usort( $bound_array_int, array( self::class, 'cmp_desc_fraction' ) );
73 +
74 + $start = 0;
75 + $end = $adjustment - 1;
76 + $length = count( $bound_array_int );
77 +
78 + for ( $i = $start; $i <= $end; $i++ ) {
79 + ++$bound_array_int[ $i % $length ]['floor'];
80 + }
81 +
82 + usort( $bound_array_int, array( self::class, 'cmp_asc_index' ) );
83 + }
84 +
85 + /**
86 + * Compare fraction values of two arrays.
87 + *
88 + * @param array $a - the first array we're comparing.
89 + * @param array $b - the second array we're comparing.
90 + *
91 + * @return int
92 + */
93 + private static function cmp_desc_fraction( $a, $b ) {
94 + return $b['fraction'] <=> $a['fraction'];
95 + }
96 +
97 + /**
98 + * Compare index values of two arrays.
99 + *
100 + * @param array $a - the first array.
101 + * @param array $b - the second array.
102 + *
103 + * @return int
104 + */
105 + private static function cmp_asc_index( $a, $b ) {
106 + return $a['index'] <=> $b['index'];
107 + }
108 +}