MediaWiki
REL1_24
|
00001 <?php 00028 class ArrayUtils { 00049 public static function consistentHashSort( &$array, $key, $separator = "\000" ) { 00050 $hashes = array(); 00051 foreach ( $array as $elt ) { 00052 $hashes[$elt] = md5( $elt . $separator . $key ); 00053 } 00054 uasort( $array, function ( $a, $b ) use ( $hashes ) { 00055 return strcmp( $hashes[$a], $hashes[$b] ); 00056 } ); 00057 } 00058 00066 public static function pickRandom( $weights ) { 00067 if ( !is_array( $weights ) || count( $weights ) == 0 ) { 00068 return false; 00069 } 00070 00071 $sum = array_sum( $weights ); 00072 if ( $sum == 0 ) { 00073 # No loads on any of them 00074 # In previous versions, this triggered an unweighted random selection, 00075 # but this feature has been removed as of April 2006 to allow for strict 00076 # separation of query groups. 00077 return false; 00078 } 00079 $max = mt_getrandmax(); 00080 $rand = mt_rand( 0, $max ) / $max * $sum; 00081 00082 $sum = 0; 00083 foreach ( $weights as $i => $w ) { 00084 $sum += $w; 00085 # Do not return keys if they have 0 weight. 00086 # Note that the "all 0 weight" case is handed above 00087 if ( $w > 0 && $sum >= $rand ) { 00088 break; 00089 } 00090 } 00091 00092 return $i; 00093 } 00094 00112 public static function findLowerBound( $valueCallback, $valueCount, 00113 $comparisonCallback, $target 00114 ) { 00115 if ( $valueCount === 0 ) { 00116 return false; 00117 } 00118 00119 $min = 0; 00120 $max = $valueCount; 00121 do { 00122 $mid = $min + ( ( $max - $min ) >> 1 ); 00123 $item = call_user_func( $valueCallback, $mid ); 00124 $comparison = call_user_func( $comparisonCallback, $target, $item ); 00125 if ( $comparison > 0 ) { 00126 $min = $mid; 00127 } elseif ( $comparison == 0 ) { 00128 $min = $mid; 00129 break; 00130 } else { 00131 $max = $mid; 00132 } 00133 } while ( $min < $max - 1 ); 00134 00135 if ( $min == 0 ) { 00136 $item = call_user_func( $valueCallback, $min ); 00137 $comparison = call_user_func( $comparisonCallback, $target, $item ); 00138 if ( $comparison < 0 ) { 00139 // Before the first item 00140 return false; 00141 } 00142 } 00143 return $min; 00144 } 00145 00158 public static function arrayDiffAssocRecursive( $array1 ) { 00159 $arrays = func_get_args(); 00160 array_shift( $arrays ); 00161 $ret = array(); 00162 00163 foreach ( $array1 as $key => $value ) { 00164 if ( is_array( $value ) ) { 00165 $args = array( $value ); 00166 foreach ( $arrays as $array ) { 00167 if ( isset( $array[$key] ) ) { 00168 $args[] = $array[$key]; 00169 } 00170 } 00171 $valueret = call_user_func_array( __METHOD__, $args ); 00172 if ( count( $valueret ) ) { 00173 $ret[$key] = $valueret; 00174 } 00175 } else { 00176 foreach ( $arrays as $array ) { 00177 if ( isset( $array[$key] ) && $array[$key] === $value ) { 00178 continue 2; 00179 } 00180 } 00181 $ret[$key] = $value; 00182 } 00183 } 00184 00185 return $ret; 00186 } 00187 }