MediaWiki  REL1_24
ArrayUtils.php
Go to the documentation of this file.
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 }