1<?php defined('SYSPATH') OR die('No direct access allowed.'); 2/** 3 * Array helper class. 4 * 5 * $Id: arr.php 4346 2009-05-11 17:08:15Z zombor $ 6 * 7 * @package Core 8 * @author Kohana Team 9 * @copyright (c) 2007-2008 Kohana Team 10 * @license http://kohanaphp.com/license.html 11 */ 12class arr_Core { 13 14 /** 15 * Return a callback array from a string, eg: limit[10,20] would become 16 * array('limit', array('10', '20')) 17 * 18 * @param string callback string 19 * @return array 20 */ 21 public static function callback_string($str) 22 { 23 // command[param,param] 24 if (preg_match('/([^\[]*+)\[(.+)\]/', (string) $str, $match)) 25 { 26 // command 27 $command = $match[1]; 28 29 // param,param 30 $params = preg_split('/(?<!\\\\),/', $match[2]); 31 $params = str_replace('\,', ',', $params); 32 } 33 else 34 { 35 // command 36 $command = $str; 37 38 // No params 39 $params = NULL; 40 } 41 42 return array($command, $params); 43 } 44 45 /** 46 * Rotates a 2D array clockwise. 47 * Example, turns a 2x3 array into a 3x2 array. 48 * 49 * @param array array to rotate 50 * @param boolean keep the keys in the final rotated array. the sub arrays of the source array need to have the same key values. 51 * if your subkeys might not match, you need to pass FALSE here! 52 * @return array 53 */ 54 public static function rotate($source_array, $keep_keys = TRUE) 55 { 56 $new_array = array(); 57 foreach ($source_array as $key => $value) 58 { 59 $value = ($keep_keys === TRUE) ? $value : array_values($value); 60 foreach ($value as $k => $v) 61 { 62 $new_array[$k][$key] = $v; 63 } 64 } 65 66 return $new_array; 67 } 68 69 /** 70 * Removes a key from an array and returns the value. 71 * 72 * @param string key to return 73 * @param array array to work on 74 * @return mixed value of the requested array key 75 */ 76 public static function remove($key, & $array) 77 { 78 if ( ! array_key_exists($key, $array)) 79 return NULL; 80 81 $val = $array[$key]; 82 unset($array[$key]); 83 84 return $val; 85 } 86 87 88 /** 89 * Extract one or more keys from an array. Each key given after the first 90 * argument (the array) will be extracted. Keys that do not exist in the 91 * search array will be NULL in the extracted data. 92 * 93 * @param array array to search 94 * @param string key name 95 * @return array 96 */ 97 public static function extract(array $search, $keys) 98 { 99 // Get the keys, removing the $search array 100 $keys = array_slice(func_get_args(), 1); 101 102 $found = array(); 103 foreach ($keys as $key) 104 { 105 if (isset($search[$key])) 106 { 107 $found[$key] = $search[$key]; 108 } 109 else 110 { 111 $found[$key] = NULL; 112 } 113 } 114 115 return $found; 116 } 117 118 /** 119 * Because PHP does not have this function. 120 * 121 * @param array array to unshift 122 * @param string key to unshift 123 * @param mixed value to unshift 124 * @return array 125 */ 126 public static function unshift_assoc( array & $array, $key, $val) 127 { 128 $array = array_reverse($array, TRUE); 129 $array[$key] = $val; 130 $array = array_reverse($array, TRUE); 131 132 return $array; 133 } 134 135 /** 136 * Because PHP does not have this function, and array_walk_recursive creates 137 * references in arrays and is not truly recursive. 138 * 139 * @param mixed callback to apply to each member of the array 140 * @param array array to map to 141 * @return array 142 */ 143 public static function map_recursive($callback, array $array) 144 { 145 foreach ($array as $key => $val) 146 { 147 // Map the callback to the key 148 $array[$key] = is_array($val) ? arr::map_recursive($callback, $val) : call_user_func($callback, $val); 149 } 150 151 return $array; 152 } 153 154 /** 155 * @param mixed $needle the value to search for 156 * @param array $haystack an array of values to search in 157 * @param boolean $sort sort the array now 158 * @return integer|FALSE the index of the match or FALSE when not found 159 */ 160 public static function binary_search($needle, $haystack, $sort = FALSE) 161 { 162 if ($sort) 163 { 164 sort($haystack); 165 } 166 167 $high = count($haystack) - 1; 168 $low = 0; 169 170 while ($low <= $high) 171 { 172 $mid = ($low + $high) >> 1; 173 174 if ($haystack[$mid] < $needle) 175 { 176 $low = $mid + 1; 177 } 178 elseif ($haystack[$mid] > $needle) 179 { 180 $high = $mid - 1; 181 } 182 else 183 { 184 return $mid; 185 } 186 } 187 188 return FALSE; 189 } 190 191 192 /** 193 * Emulates array_merge_recursive, but appends numeric keys and replaces 194 * associative keys, instead of appending all keys. 195 * 196 * @param array any number of arrays 197 * @return array 198 */ 199 public static function merge() 200 { 201 $total = func_num_args(); 202 203 $result = array(); 204 for ($i = 0; $i < $total; $i++) 205 { 206 foreach (func_get_arg($i) as $key => $val) 207 { 208 if (isset($result[$key])) 209 { 210 if (is_array($val)) 211 { 212 // Arrays are merged recursively 213 $result[$key] = arr::merge($result[$key], $val); 214 } 215 elseif (is_int($key)) 216 { 217 // Indexed arrays are appended 218 array_push($result, $val); 219 } 220 else 221 { 222 // Associative arrays are replaced 223 $result[$key] = $val; 224 } 225 } 226 else 227 { 228 // New values are added 229 $result[$key] = $val; 230 } 231 } 232 } 233 234 return $result; 235 } 236 237 /** 238 * Overwrites an array with values from input array(s). 239 * Non-existing keys will not be appended! 240 * 241 * @param array key array 242 * @param array input array(s) that will overwrite key array values 243 * @return array 244 */ 245 public static function overwrite($array1, $array2) 246 { 247 foreach (array_intersect_key($array2, $array1) as $key => $value) 248 { 249 $array1[$key] = $value; 250 } 251 252 if (func_num_args() > 2) 253 { 254 foreach (array_slice(func_get_args(), 2) as $array2) 255 { 256 foreach (array_intersect_key($array2, $array1) as $key => $value) 257 { 258 $array1[$key] = $value; 259 } 260 } 261 } 262 263 return $array1; 264 } 265 266 /** 267 * Fill an array with a range of numbers. 268 * 269 * @param integer stepping 270 * @param integer ending number 271 * @return array 272 */ 273 public static function range($step = 10, $max = 100) 274 { 275 if ($step < 1) 276 return array(); 277 278 $array = array(); 279 for ($i = $step; $i <= $max; $i += $step) 280 { 281 $array[$i] = $i; 282 } 283 284 return $array; 285 } 286 287 /** 288 * Recursively convert an array to an object. 289 * 290 * @param array array to convert 291 * @return object 292 */ 293 public static function to_object(array $array, $class = 'stdClass') 294 { 295 $object = new $class; 296 297 foreach ($array as $key => $value) 298 { 299 if (is_array($value)) 300 { 301 // Convert the array to an object 302 $value = arr::to_object($value, $class); 303 } 304 305 // Add the value to the object 306 $object->{$key} = $value; 307 } 308 309 return $object; 310 } 311 312} // End arr 313