MediaWiki  master
ArrayUtils.php
Go to the documentation of this file.
1 <?php
28 class ArrayUtils {
49  public static function consistentHashSort( &$array, $key, $separator = "\000" ) {
50  $hashes = [];
51  foreach ( $array as $elt ) {
52  $hashes[$elt] = md5( $elt . $separator . $key );
53  }
54  uasort( $array, static function ( $a, $b ) use ( $hashes ) {
55  return strcmp( $hashes[$a], $hashes[$b] );
56  } );
57  }
58 
66  public static function pickRandom( $weights ) {
67  if ( !is_array( $weights ) || count( $weights ) == 0 ) {
68  return false;
69  }
70 
71  $sum = array_sum( $weights );
72  if ( $sum == 0 ) {
73  # No loads on any of them
74  # In previous versions, this triggered an unweighted random selection,
75  # but this feature has been removed as of April 2006 to allow for strict
76  # separation of query groups.
77  return false;
78  }
79  $max = mt_getrandmax();
80  $rand = mt_rand( 0, $max ) / $max * $sum;
81 
82  $sum = 0;
83  foreach ( $weights as $i => $w ) {
84  $sum += $w;
85  # Do not return keys if they have 0 weight.
86  # Note that the "all 0 weight" case is handed above
87  if ( $w > 0 && $sum >= $rand ) {
88  break;
89  }
90  }
91 
92  // @phan-suppress-next-line PhanPossiblyUndeclaredVariable weight is non-empty and i is always set
93  return $i;
94  }
95 
113  public static function findLowerBound( $valueCallback, $valueCount,
114  $comparisonCallback, $target
115  ) {
116  if ( $valueCount === 0 ) {
117  return false;
118  }
119 
120  $min = 0;
121  $max = $valueCount;
122  do {
123  $mid = $min + ( ( $max - $min ) >> 1 );
124  $item = $valueCallback( $mid );
125  $comparison = $comparisonCallback( $target, $item );
126  if ( $comparison > 0 ) {
127  $min = $mid;
128  } elseif ( $comparison == 0 ) {
129  $min = $mid;
130  break;
131  } else {
132  $max = $mid;
133  }
134  } while ( $min < $max - 1 );
135 
136  if ( $min == 0 ) {
137  $item = $valueCallback( $min );
138  $comparison = $comparisonCallback( $target, $item );
139  if ( $comparison < 0 ) {
140  // Before the first item
141  return false;
142  }
143  }
144  return $min;
145  }
146 
159  public static function arrayDiffAssocRecursive( $array1, ...$arrays ) {
160  $ret = [];
161 
162  foreach ( $array1 as $key => $value ) {
163  if ( is_array( $value ) ) {
164  $args = [ $value ];
165  foreach ( $arrays as $array ) {
166  if ( isset( $array[$key] ) ) {
167  $args[] = $array[$key];
168  }
169  }
170  $valueret = self::arrayDiffAssocRecursive( ...$args );
171  if ( count( $valueret ) ) {
172  $ret[$key] = $valueret;
173  }
174  } else {
175  foreach ( $arrays as $array ) {
176  if ( isset( $array[$key] ) && $array[$key] === $value ) {
177  continue 2;
178  }
179  }
180  $ret[$key] = $value;
181  }
182  }
183 
184  return $ret;
185  }
186 
211  public static function cartesianProduct( ...$inputArrays ) {
212  $numInputs = count( $inputArrays );
213  if ( $numInputs === 0 ) {
214  return [];
215  }
216 
217  // Reset the internal pointers
218  foreach ( $inputArrays as &$inputArray ) {
219  if ( !count( $inputArray ) ) {
220  return [];
221  }
222  reset( $inputArray );
223  }
224  unset( $inputArray );
225 
226  $outputArrays = [];
227  $done = false;
228  while ( !$done ) {
229  // Construct the output array element
230  $element = [];
231  foreach ( $inputArrays as $paramIndex => $inputArray ) {
232  $element[] = current( $inputArray );
233  }
234  $outputArrays[] = $element;
235 
236  // Increment the pointers starting from the least significant.
237  // If the least significant rolls over back to the start of the
238  // array, continue with the next most significant, and so on until
239  // that stops happening. If all pointers roll over, we are done.
240  $done = true;
241  for ( $paramIndex = $numInputs - 1; $paramIndex >= 0; $paramIndex-- ) {
242  next( $inputArrays[$paramIndex] );
243  if ( key( $inputArrays[$paramIndex] ) === null ) {
244  reset( $inputArrays[$paramIndex] );
245  // continue
246  } else {
247  $done = false;
248  break;
249  }
250  }
251  }
252  return $outputArrays;
253  }
254 }
A collection of static methods to play with arrays.
Definition: ArrayUtils.php:28
static arrayDiffAssocRecursive( $array1,... $arrays)
Do array_diff_assoc() on multi-dimensional arrays.
Definition: ArrayUtils.php:159
static consistentHashSort(&$array, $key, $separator="\000")
Sort the given array in a pseudo-random order which depends only on the given key and each element va...
Definition: ArrayUtils.php:49
static findLowerBound( $valueCallback, $valueCount, $comparisonCallback, $target)
Do a binary search, and return the index of the largest item that sorts less than or equal to the tar...
Definition: ArrayUtils.php:113
static pickRandom( $weights)
Given an array of non-normalised probabilities, this function will select an element and return the a...
Definition: ArrayUtils.php:66
static cartesianProduct(... $inputArrays)
Make an array consisting of every combination of the elements of the input arrays.
Definition: ArrayUtils.php:211
if( $line===false) $args
Definition: mcc.php:124