1 | <?php |
||||||
2 | |||||||
3 | class HelperArray { |
||||||
4 | |||||||
5 | /** |
||||||
6 | * Overwrites old array with new |
||||||
7 | */ |
||||||
8 | const MERGE_OVERWRITE = 0; |
||||||
9 | /** |
||||||
10 | * Merges old array with new with array_merge() |
||||||
11 | * String keys replaced, numeric keys renumbered |
||||||
12 | */ |
||||||
13 | const MERGE_PHP = 1; |
||||||
14 | |||||||
15 | /** |
||||||
16 | * Merges old array with new with array_merge_recursive() |
||||||
17 | * String keys replaced, numeric keys renumbered |
||||||
18 | */ |
||||||
19 | const MERGE_RECURSIVE = 2; |
||||||
20 | |||||||
21 | /** |
||||||
22 | * Merges old array with new recursive |
||||||
23 | * String keys merged, numeric keys merged |
||||||
24 | */ |
||||||
25 | const MERGE_RECURSIVE_NUMERIC = 3; |
||||||
26 | |||||||
27 | |||||||
28 | /** |
||||||
29 | * No array cloning - just stay with same objects |
||||||
30 | */ |
||||||
31 | const CLONE_ARRAY_NONE = 0; |
||||||
32 | /** |
||||||
33 | * Clone objects on first level of array |
||||||
34 | */ |
||||||
35 | const CLONE_ARRAY_SHALLOW = 1; |
||||||
36 | /** |
||||||
37 | * Clone objects recursive on any array level |
||||||
38 | */ |
||||||
39 | const CLONE_ARRAY_RECURSIVE = 2; |
||||||
40 | |||||||
41 | /** |
||||||
42 | * Convert $delimiter delimited string to array |
||||||
43 | * |
||||||
44 | * @param mixed $string |
||||||
45 | * @param string $delimiter |
||||||
46 | * |
||||||
47 | * @return array |
||||||
48 | */ |
||||||
49 | 6 | public static function stringToArray($string, $delimiter = ',') { |
|||||
50 | 6 | return is_string($string) && !empty($string) ? explode($delimiter, $string) : array(); |
|||||
51 | } |
||||||
52 | |||||||
53 | /** |
||||||
54 | * Convert single value to array by reference |
||||||
55 | * |
||||||
56 | * @param mixed &$value |
||||||
57 | */ |
||||||
58 | 3 | public static function makeArrayRef(&$value, $index = 0) { |
|||||
59 | 3 | if (!is_array($value)) { |
|||||
60 | 2 | $value = array($index => $value); |
|||||
61 | 2 | } |
|||||
62 | 3 | } |
|||||
63 | |||||||
64 | |||||||
65 | /** |
||||||
66 | * Convert single value to array |
||||||
67 | * |
||||||
68 | * @param mixed $value |
||||||
69 | * |
||||||
70 | * @return array |
||||||
71 | */ |
||||||
72 | 3 | public static function makeArray($value, $index = 0) { |
|||||
73 | 3 | static::makeArrayRef($value, $index); |
|||||
74 | |||||||
75 | 3 | return $value; |
|||||
76 | } |
||||||
77 | |||||||
78 | /** |
||||||
79 | * Filters array by callback |
||||||
80 | * |
||||||
81 | * @param mixed $array |
||||||
82 | * @param callable $callback |
||||||
83 | * |
||||||
84 | * @return array |
||||||
85 | */ |
||||||
86 | 15 | public static function filter(&$array, $callback) { |
|||||
87 | 15 | $result = array(); |
|||||
88 | |||||||
89 | 15 | if (is_array($array) && !empty($array)) { |
|||||
90 | // TODO - array_filter |
||||||
91 | 10 | foreach ($array as $value) { |
|||||
92 | 10 | if (call_user_func($callback, $value)) { |
|||||
93 | 6 | $result[] = $value; |
|||||
94 | 6 | } |
|||||
95 | 10 | } |
|||||
96 | 10 | } |
|||||
97 | |||||||
98 | 15 | return $result; |
|||||
99 | } |
||||||
100 | |||||||
101 | /** |
||||||
102 | * Filters array by callback |
||||||
103 | * |
||||||
104 | * @param mixed $array |
||||||
105 | * @param callable $callback |
||||||
106 | * @param bool $withKeys |
||||||
107 | * |
||||||
108 | * @return array |
||||||
109 | */ |
||||||
110 | public static function map(&$array, $callback, $withKeys = false) { |
||||||
111 | $result = array(); |
||||||
112 | |||||||
113 | if (is_array($array) && !empty($array)) { |
||||||
114 | if ($withKeys) { |
||||||
115 | $result = array_map($callback, $array, array_keys($array)); |
||||||
116 | } else { |
||||||
117 | $result = array_map($callback, $array); |
||||||
118 | } |
||||||
119 | } |
||||||
120 | |||||||
121 | return $result; |
||||||
122 | } |
||||||
123 | |||||||
124 | /** |
||||||
125 | * Filter empty() values from array |
||||||
126 | * |
||||||
127 | * @param $array |
||||||
128 | * |
||||||
129 | * @return array |
||||||
130 | */ |
||||||
131 | 8 | public static function filterEmpty($array) { |
|||||
132 | 8 | return static::filter($array, 'Validators::isNotEmpty'); |
|||||
133 | } |
||||||
134 | |||||||
135 | /** |
||||||
136 | * @param string $string |
||||||
137 | * @param string $delimiter |
||||||
138 | * |
||||||
139 | * @return array |
||||||
140 | */ |
||||||
141 | 1 | public static function stringToArrayFilterEmpty($string, $delimiter = ',') { |
|||||
142 | 1 | return static::filterEmpty(static::stringToArray($string, $delimiter)); |
|||||
143 | } |
||||||
144 | |||||||
145 | /** |
||||||
146 | * @param mixed|array &$arrayOld |
||||||
147 | * @param mixed|array $arrayNew |
||||||
148 | * @param int $mergeStrategy - default is HelperArray::MERGE_OVERWRITE |
||||||
149 | */ |
||||||
150 | 1 | public static function merge(&$arrayOld, $arrayNew = array(), $mergeStrategy = self::MERGE_OVERWRITE) { |
|||||
151 | 1 | static::makeArrayRef($arrayNew); |
|||||
152 | 1 | static::makeArrayRef($arrayOld); |
|||||
153 | |||||||
154 | switch ($mergeStrategy) { |
||||||
155 | 1 | case self::MERGE_PHP: |
|||||
156 | 1 | $arrayOld = array_merge($arrayOld, $arrayNew); |
|||||
157 | 1 | break; |
|||||
158 | |||||||
159 | 1 | case self::MERGE_RECURSIVE: |
|||||
160 | $arrayOld = array_merge_recursive($arrayOld, $arrayNew); |
||||||
161 | break; |
||||||
162 | |||||||
163 | 1 | case self::MERGE_RECURSIVE_NUMERIC: |
|||||
164 | foreach ($arrayNew as $key => $value) { |
||||||
165 | !isset($arrayOld[$key]) || !is_array($arrayOld[$key]) ? $arrayOld[$key] = $value : self::merge($arrayOld[$key], $value, self::MERGE_RECURSIVE_NUMERIC); |
||||||
166 | } |
||||||
167 | break; |
||||||
168 | |||||||
169 | 1 | default: |
|||||
170 | 1 | $arrayOld = $arrayNew; |
|||||
171 | 1 | break; |
|||||
172 | 1 | } |
|||||
173 | 1 | } |
|||||
174 | |||||||
175 | /** |
||||||
176 | * Checks if key exists in array. If yes - return value on key otherwise return default value |
||||||
177 | * |
||||||
178 | * @param array &$array |
||||||
179 | * @param mixed $key |
||||||
180 | * @param mixed $default |
||||||
181 | * |
||||||
182 | * @return mixed |
||||||
183 | */ |
||||||
184 | 1 | public static function keyExistsOr(&$array, $key, $default) { |
|||||
185 | 1 | return array_key_exists($key, $array) ? $array[$key] : $default; |
|||||
186 | } |
||||||
187 | |||||||
188 | /** |
||||||
189 | * Clone objects in array |
||||||
190 | * |
||||||
191 | * @param array &$array - Any dimensional array with presumed objects in there |
||||||
192 | * @param int $deep - HelperArray::CLONE_ARRAY_xxx constants |
||||||
193 | */ |
||||||
194 | 3 | public static function cloneDeep(&$array, $deep = self::CLONE_ARRAY_RECURSIVE) { |
|||||
195 | 3 | if ($deep == self::CLONE_ARRAY_NONE) { |
|||||
196 | 1 | return; |
|||||
197 | } |
||||||
198 | |||||||
199 | 2 | foreach ($array as &$value) { |
|||||
200 | 2 | if (is_object($value)) { |
|||||
201 | 2 | $value = clone $value; |
|||||
202 | 2 | } elseif (is_array($value) && $deep == self::CLONE_ARRAY_RECURSIVE) { |
|||||
203 | 1 | static::cloneDeep($value, $deep); |
|||||
204 | 1 | } |
|||||
205 | 2 | } |
|||||
206 | 2 | } |
|||||
207 | |||||||
208 | /** |
||||||
209 | * Repacking array to provided level, removing null elements |
||||||
210 | * |
||||||
211 | * @param array &$array |
||||||
212 | * @param int $level |
||||||
213 | */ |
||||||
214 | public static function array_repack(&$array, $level = 0) { |
||||||
215 | if (!is_array($array)) { |
||||||
0 ignored issues
–
show
introduced
by
![]() |
|||||||
216 | return; |
||||||
217 | } |
||||||
218 | |||||||
219 | foreach ($array as $key => &$value) { |
||||||
220 | if ($value === null) { |
||||||
221 | unset($array[$key]); |
||||||
222 | } elseif ($level > 0 && is_array($value)) { |
||||||
223 | static::array_repack($value, $level - 1); |
||||||
224 | if (empty($value)) { |
||||||
225 | unset($array[$key]); |
||||||
226 | } |
||||||
227 | } |
||||||
228 | } |
||||||
229 | } |
||||||
230 | |||||||
231 | |||||||
232 | /** |
||||||
233 | * Parses array of stringified parameters to array of parameter |
||||||
234 | * |
||||||
235 | * Stringified parameter is a string of "<parmName><delimeter><paramValue>" |
||||||
236 | * |
||||||
237 | * @param array|string $array |
||||||
238 | * @param string $delimiter |
||||||
239 | * |
||||||
240 | * @return array |
||||||
241 | */ |
||||||
242 | public static function parseParamStrings($array, $delimiter = '=') { |
||||||
243 | !is_array($array) ? $array = array((string)$array) : false; |
||||||
244 | |||||||
245 | $result = array(); |
||||||
246 | foreach ($array as $param) { |
||||||
247 | $exploded = explode($delimiter, $param); |
||||||
248 | $paramName = $exploded[0]; |
||||||
249 | unset($exploded[0]); |
||||||
250 | $result[$paramName] = implode($delimiter, $exploded); |
||||||
251 | } |
||||||
252 | |||||||
253 | return $result; |
||||||
254 | } |
||||||
255 | |||||||
256 | /** |
||||||
257 | * Finds maximum value of field in subarrays |
||||||
258 | * |
||||||
259 | * @param array[] $array |
||||||
260 | * @param mixed $fieldName |
||||||
261 | * |
||||||
262 | * @return float|null |
||||||
263 | */ |
||||||
264 | public static function maxValueByField(&$array, $fieldName) { |
||||||
265 | return array_reduce($array, function ($carry, $item) use ($fieldName) { |
||||||
266 | if(is_array($item) && isset($item[$fieldName]) && (!isset($carry) || $carry < $item[$fieldName])) { |
||||||
267 | $carry = $item[$fieldName]; |
||||||
268 | } |
||||||
269 | |||||||
270 | return $carry; |
||||||
271 | }); |
||||||
272 | } |
||||||
273 | |||||||
274 | /** |
||||||
275 | * @param $array |
||||||
276 | * @param $fieldName |
||||||
277 | */ |
||||||
278 | public static function topRecordsByField(&$array, $fieldName) { |
||||||
279 | $maxValue = self::maxValueByField($array, $fieldName); |
||||||
280 | |||||||
281 | return |
||||||
282 | array_reduce($array, |
||||||
283 | function ($carry, $item) use (&$fieldName, $maxValue) { |
||||||
284 | if(is_array($item) && isset($item[$fieldName]) && $item[$fieldName] == $maxValue) { |
||||||
285 | $carry[] = $item; |
||||||
286 | } |
||||||
287 | |||||||
288 | return $carry; |
||||||
289 | }, |
||||||
290 | array() |
||||||
291 | ); |
||||||
292 | } |
||||||
293 | |||||||
294 | public static function intersectByKeys(array &$array1, array &$array2) { |
||||||
295 | return array_uintersect_assoc($array1, $array2, function ($a, $b) {return 0;}); |
||||||
0 ignored issues
–
show
The parameter
$a is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() The parameter
$b is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
296 | } |
||||||
297 | |||||||
298 | /** |
||||||
299 | * Get first key of array |
||||||
300 | * Polyfill until PHP 7.3 |
||||||
301 | * |
||||||
302 | * @param array $array |
||||||
303 | * |
||||||
304 | * @return mixed|null |
||||||
305 | */ |
||||||
306 | public static function array_key_first(&$array) { |
||||||
307 | if (!is_array($array)) { |
||||||
0 ignored issues
–
show
|
|||||||
308 | return null; |
||||||
309 | } |
||||||
310 | reset($array); |
||||||
311 | |||||||
312 | return key($array); |
||||||
313 | } |
||||||
314 | |||||||
315 | } |
||||||
316 |