Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ArrayHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ArrayHelper, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | final class ArrayHelper |
||
19 | { |
||
20 | /** |
||
21 | * Private constructor to prevent instantiation of this class |
||
22 | * |
||
23 | * @since 1.0 |
||
24 | */ |
||
25 | private function __construct() |
||
28 | |||
29 | /** |
||
30 | * Function to convert array to integer values |
||
31 | * |
||
32 | * @param array $array The source array to convert |
||
33 | * @param mixed $default A default value (int|array) to assign if $array is not an array |
||
34 | * |
||
35 | * @return array |
||
36 | * |
||
37 | * @since 1.0 |
||
38 | */ |
||
39 | public static function toInteger($array, $default = null) |
||
58 | |||
59 | /** |
||
60 | * Utility function to map an array to a stdClass object. |
||
61 | * |
||
62 | * @param array $array The array to map. |
||
63 | * @param string $class Name of the class to create |
||
64 | * @param boolean $recursive Convert also any array inside the main array |
||
65 | * |
||
66 | * @return object |
||
67 | * |
||
68 | * @since 1.0 |
||
69 | */ |
||
70 | public static function toObject(array $array, $class = 'stdClass', $recursive = true) |
||
88 | |||
89 | /** |
||
90 | * Utility function to map an array to a string. |
||
91 | * |
||
92 | * @param array $array The array to map. |
||
93 | * @param string $inner_glue The glue (optional, defaults to '=') between the key and the value. |
||
94 | * @param string $outer_glue The glue (optional, defaults to ' ') between array elements. |
||
95 | * @param boolean $keepOuterKey True if final key should be kept. |
||
96 | * |
||
97 | * @return string |
||
98 | * |
||
99 | * @since 1.0 |
||
100 | */ |
||
101 | public static function toString(array $array, $inner_glue = '=', $outer_glue = ' ', $keepOuterKey = false) |
||
125 | |||
126 | /** |
||
127 | * Utility function to map an object to an array |
||
128 | * |
||
129 | * @param object $p_obj The source object |
||
130 | * @param boolean $recurse True to recurse through multi-level objects |
||
131 | * @param string $regex An optional regular expression to match on field names |
||
132 | * |
||
133 | * @return array |
||
134 | * |
||
135 | * @since 1.0 |
||
136 | */ |
||
137 | public static function fromObject($p_obj, $recurse = true, $regex = null) |
||
146 | |||
147 | /** |
||
148 | * Utility function to map an object or array to an array |
||
149 | * |
||
150 | * @param mixed $item The source object or array |
||
151 | * @param boolean $recurse True to recurse through multi-level objects |
||
152 | * @param string $regex An optional regular expression to match on field names |
||
153 | * |
||
154 | * @return array |
||
155 | * |
||
156 | * @since 1.0 |
||
157 | */ |
||
158 | private static function arrayFromObject($item, $recurse, $regex) |
||
196 | |||
197 | /** |
||
198 | * Extracts a column from an array of arrays or objects |
||
199 | * |
||
200 | * @param array $array The source array |
||
201 | * @param string $valueCol The index of the column or name of object property to be used as value |
||
202 | * It may also be NULL to return complete arrays or objects (this is |
||
203 | * useful together with <var>$keyCol</var> to reindex the array). |
||
204 | * @param string $keyCol The index of the column or name of object property to be used as key |
||
205 | * |
||
206 | * @return array Column of values from the source array |
||
207 | * |
||
208 | * @since 1.0 |
||
209 | * @see http://php.net/manual/en/language.types.array.php |
||
210 | * @see http://php.net/manual/en/function.array-column.php |
||
211 | */ |
||
212 | public static function getColumn(array $array, $valueCol, $keyCol = null) |
||
245 | |||
246 | /** |
||
247 | * Utility function to return a value from a named array or a specified default |
||
248 | * |
||
249 | * @param array|\ArrayAccess $array A named array or object that implements ArrayAccess |
||
250 | * @param string $name The key to search for |
||
251 | * @param mixed $default The default value to give if no key found |
||
252 | * @param string $type Return type for the variable (INT, FLOAT, STRING, WORD, BOOLEAN, ARRAY) |
||
253 | * |
||
254 | * @return mixed |
||
255 | * |
||
256 | * @since 1.0 |
||
257 | * @throws \InvalidArgumentException |
||
258 | */ |
||
259 | public static function getValue($array, $name, $default = null, $type = '') |
||
324 | |||
325 | /** |
||
326 | * Takes an associative array of arrays and inverts the array keys to values using the array values as keys. |
||
327 | * |
||
328 | * Example: |
||
329 | * $input = array( |
||
330 | * 'New' => array('1000', '1500', '1750'), |
||
331 | * 'Used' => array('3000', '4000', '5000', '6000') |
||
332 | * ); |
||
333 | * $output = ArrayHelper::invert($input); |
||
334 | * |
||
335 | * Output would be equal to: |
||
336 | * $output = array( |
||
337 | * '1000' => 'New', |
||
338 | * '1500' => 'New', |
||
339 | * '1750' => 'New', |
||
340 | * '3000' => 'Used', |
||
341 | * '4000' => 'Used', |
||
342 | * '5000' => 'Used', |
||
343 | * '6000' => 'Used' |
||
344 | * ); |
||
345 | * |
||
346 | * @param array $array The source array. |
||
347 | * |
||
348 | * @return array |
||
349 | * |
||
350 | * @since 1.0 |
||
351 | */ |
||
352 | public static function invert(array $array) |
||
375 | |||
376 | /** |
||
377 | * Method to determine if an array is an associative array. |
||
378 | * |
||
379 | * @param array $array An array to test. |
||
380 | * |
||
381 | * @return boolean |
||
382 | * |
||
383 | * @since 1.0 |
||
384 | */ |
||
385 | public static function isAssociative($array) |
||
400 | |||
401 | /** |
||
402 | * Pivots an array to create a reverse lookup of an array of scalars, arrays or objects. |
||
403 | * |
||
404 | * @param array $source The source array. |
||
405 | * @param string $key Where the elements of the source array are objects or arrays, the key to pivot on. |
||
406 | * |
||
407 | * @return array An array of arrays pivoted either on the value of the keys, or an individual key of an object or array. |
||
408 | * |
||
409 | * @since 1.0 |
||
410 | */ |
||
411 | public static function pivot(array $source, $key = null) |
||
475 | |||
476 | /** |
||
477 | * Utility function to sort an array of objects on a given field |
||
478 | * |
||
479 | * @param array $a An array of objects |
||
480 | * @param mixed $k The key (string) or an array of keys to sort on |
||
481 | * @param mixed $direction Direction (integer) or an array of direction to sort in [1 = Ascending] [-1 = Descending] |
||
482 | * @param mixed $caseSensitive Boolean or array of booleans to let sort occur case sensitive or insensitive |
||
483 | * @param mixed $locale Boolean or array of booleans to let sort occur using the locale language or not |
||
484 | * |
||
485 | * @return array |
||
486 | * |
||
487 | * @since 1.0 |
||
488 | */ |
||
489 | public static function sortObjects(array $a, $k, $direction = 1, $caseSensitive = true, $locale = false) |
||
554 | |||
555 | /** |
||
556 | * Multidimensional array safe unique test |
||
557 | * |
||
558 | * @param array $array The array to make unique. |
||
559 | * |
||
560 | * @return array |
||
561 | * |
||
562 | * @see http://php.net/manual/en/function.array-unique.php |
||
563 | * @since 1.0 |
||
564 | */ |
||
565 | public static function arrayUnique(array $array) |
||
573 | |||
574 | /** |
||
575 | * An improved array_search that allows for partial matching of strings values in associative arrays. |
||
576 | * |
||
577 | * @param string $needle The text to search for within the array. |
||
578 | * @param array $haystack Associative array to search in to find $needle. |
||
579 | * @param boolean $caseSensitive True to search case sensitive, false otherwise. |
||
580 | * |
||
581 | * @return mixed Returns the matching array $key if found, otherwise false. |
||
582 | * |
||
583 | * @since 1.0 |
||
584 | */ |
||
585 | public static function arraySearch($needle, array $haystack, $caseSensitive = true) |
||
599 | |||
600 | /** |
||
601 | * Method to recursively convert data to a one dimension array. |
||
602 | * |
||
603 | * @param array|object $array The array or object to convert. |
||
604 | * @param string $separator The key separator. |
||
605 | * @param string $prefix Last level key prefix. |
||
606 | * |
||
607 | * @return array |
||
608 | * |
||
609 | * @since 1.3.0 |
||
610 | */ |
||
611 | public static function flatten($array, $separator = '.', $prefix = '') |
||
638 | } |
||
639 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.