Initial Kohana install
[speedfreak] / Server / system / helpers / arr.php
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  */
12 class 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