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 Arrayy 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 Arrayy, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
11 | class Arrayy extends CollectionMethods implements \Countable, \IteratorAggregate, \ArrayAccess |
||
12 | { |
||
13 | |||
14 | /** |
||
15 | * @var array |
||
16 | */ |
||
17 | private $array = array(); |
||
18 | |||
19 | /** |
||
20 | * Initializes |
||
21 | * |
||
22 | * @param array $array |
||
23 | */ |
||
24 | 244 | public function __construct($array = array()) |
|
46 | |||
47 | /** |
||
48 | * magic to string |
||
49 | * |
||
50 | * @return string |
||
51 | */ |
||
52 | 13 | public function __toString() |
|
56 | |||
57 | /** |
||
58 | * Get a data by key |
||
59 | * |
||
60 | * @param $key |
||
61 | * |
||
62 | * @return mixed |
||
63 | */ |
||
64 | public function &__get($key) |
||
68 | |||
69 | /** |
||
70 | * Assigns a value to the specified data |
||
71 | * |
||
72 | * @param $key |
||
73 | * @param $value |
||
74 | */ |
||
75 | public function __set($key, $value) |
||
79 | |||
80 | /** |
||
81 | * Whether or not an data exists by key |
||
82 | * |
||
83 | * @param $key |
||
84 | * |
||
85 | * @return bool |
||
86 | */ |
||
87 | public function __isset($key) |
||
91 | |||
92 | /** |
||
93 | * Unsets an data by key |
||
94 | * |
||
95 | * @param mixed $key |
||
96 | */ |
||
97 | public function __unset($key) |
||
101 | |||
102 | /** |
||
103 | * Assigns a value to the specified offset |
||
104 | * |
||
105 | * |
||
106 | * @param mixed $offset |
||
107 | * @param mixed $value |
||
108 | */ |
||
109 | public function offsetSet($offset, $value) |
||
117 | |||
118 | /** |
||
119 | * Whether or not an offset exists |
||
120 | * |
||
121 | * @param mixed $offset |
||
122 | * |
||
123 | * @return bool |
||
124 | */ |
||
125 | 3 | public function offsetExists($offset) |
|
129 | |||
130 | /** |
||
131 | * Unsets an offset |
||
132 | * |
||
133 | * @param mixed $offset |
||
134 | */ |
||
135 | public function offsetUnset($offset) |
||
141 | |||
142 | /** |
||
143 | * Returns the value at specified offset |
||
144 | * |
||
145 | * @param mixed $offset |
||
146 | * |
||
147 | * @return null |
||
148 | */ |
||
149 | 3 | public function offsetGet($offset) |
|
153 | |||
154 | /** |
||
155 | * Returns a new ArrayIterator, thus implementing the IteratorAggregate |
||
156 | * interface. |
||
157 | * |
||
158 | * @return \ArrayIterator An iterator for the values in the array |
||
159 | */ |
||
160 | 1 | public function getIterator() |
|
164 | |||
165 | /** |
||
166 | * call object as function |
||
167 | * |
||
168 | * @param mixed $key |
||
169 | * |
||
170 | * @return mixed |
||
171 | */ |
||
172 | public function __invoke($key = null) |
||
184 | |||
185 | /** |
||
186 | * get the current array from the "Arrayy"-object |
||
187 | * |
||
188 | * @return array |
||
189 | */ |
||
190 | 144 | public function getArray() |
|
194 | |||
195 | /** |
||
196 | * Creates a Arrayy object |
||
197 | * |
||
198 | * @param array $array |
||
199 | * |
||
200 | * @return self |
||
201 | */ |
||
202 | 185 | public static function create($array = array()) |
|
206 | |||
207 | //////////////////////////////////////////////////////////////////// |
||
208 | ///////////////////////////// ANALYZE ////////////////////////////// |
||
209 | //////////////////////////////////////////////////////////////////// |
||
210 | |||
211 | /** |
||
212 | * Search for the value of the current array via $index. |
||
213 | * |
||
214 | * @param mixed $index |
||
215 | * |
||
216 | * @return self |
||
217 | */ |
||
218 | 7 | public function searchValue($index) |
|
233 | |||
234 | /** |
||
235 | * Search for the index of the current array via $value. |
||
236 | * |
||
237 | * @param mixed $value |
||
238 | * |
||
239 | * @return self |
||
240 | */ |
||
241 | 7 | public function searchIndex($value) |
|
253 | |||
254 | /** |
||
255 | * Check if all items in an array match a truth test. |
||
256 | * |
||
257 | * @param \Closure $closure |
||
258 | * |
||
259 | * @return bool |
||
260 | */ |
||
261 | 8 | View Code Duplication | public function matches(\Closure $closure) |
274 | |||
275 | /** |
||
276 | * Check if any item in an array matches a truth test. |
||
277 | * |
||
278 | * @param \Closure $closure |
||
279 | * |
||
280 | * @return bool |
||
281 | */ |
||
282 | 8 | View Code Duplication | public function matchesAny(\Closure $closure) |
295 | |||
296 | /** |
||
297 | * Check if an item is in an array. |
||
298 | * |
||
299 | * @param mixed $value |
||
300 | * |
||
301 | * @return bool |
||
302 | */ |
||
303 | 9 | public function contains($value) |
|
307 | |||
308 | /** |
||
309 | * Returns the average value of an array. |
||
310 | * |
||
311 | * @param int $decimals The number of decimals to return |
||
312 | * |
||
313 | * @return int The average value |
||
314 | */ |
||
315 | 10 | public function average($decimals = null) |
|
329 | |||
330 | /** |
||
331 | * Count the values from the current array. |
||
332 | * |
||
333 | * INFO: only a alias for "$arrayy->size()" |
||
334 | * |
||
335 | * @return int |
||
336 | */ |
||
337 | public function length() |
||
341 | |||
342 | /** |
||
343 | * Count the values from the current array. |
||
344 | * |
||
345 | * INFO: only a alias for "$arrayy->size()" |
||
346 | * |
||
347 | * @return int |
||
348 | */ |
||
349 | 40 | public function count() |
|
353 | |||
354 | /** |
||
355 | * Get the size of an array. |
||
356 | * |
||
357 | * @return int |
||
358 | */ |
||
359 | 40 | public function size() |
|
363 | |||
364 | /** |
||
365 | * Get the max value from an array. |
||
366 | * |
||
367 | * @return mixed |
||
368 | */ |
||
369 | 10 | public function max() |
|
377 | |||
378 | /** |
||
379 | * Get the min value from an array. |
||
380 | * |
||
381 | * @return mixed |
||
382 | */ |
||
383 | 10 | public function min() |
|
391 | |||
392 | //////////////////////////////////////////////////////////////////// |
||
393 | //////////////////////////// FETCH FROM //////////////////////////// |
||
394 | //////////////////////////////////////////////////////////////////// |
||
395 | |||
396 | /** |
||
397 | * Find the first item in an array that passes the truth test, |
||
398 | * otherwise return false |
||
399 | * |
||
400 | * @param \Closure $closure |
||
401 | * |
||
402 | * @return mixed|false false if we couldn't find the value |
||
403 | */ |
||
404 | 7 | public function find(\Closure $closure) |
|
414 | |||
415 | /** |
||
416 | * Clean all falsy values from an array. |
||
417 | * |
||
418 | * @return self |
||
419 | */ |
||
420 | 7 | public function clean() |
|
428 | |||
429 | /** |
||
430 | * Get a random string from an array. |
||
431 | * |
||
432 | * @param null $take |
||
433 | * |
||
434 | * @return self |
||
435 | */ |
||
436 | 5 | public function random($take = null) |
|
446 | |||
447 | /** |
||
448 | * Return an array with all elements found in input array. |
||
449 | * |
||
450 | * @param array $search |
||
451 | * |
||
452 | * @return self |
||
453 | */ |
||
454 | 2 | public function intersection(array $search) |
|
458 | |||
459 | /** |
||
460 | * Return a boolean flag which indicates whether the two input arrays have any common elements. |
||
461 | * |
||
462 | * @param array $search |
||
463 | * |
||
464 | * @return bool |
||
465 | */ |
||
466 | 1 | public function intersects(array $search) |
|
470 | |||
471 | //////////////////////////////////////////////////////////////////// |
||
472 | ///////////////////////////// SLICERS ////////////////////////////// |
||
473 | //////////////////////////////////////////////////////////////////// |
||
474 | |||
475 | /** |
||
476 | * Get the first value from an array. |
||
477 | * |
||
478 | * @param int|null $take |
||
479 | * |
||
480 | * @return self |
||
481 | */ |
||
482 | 27 | public function first($take = null) |
|
492 | |||
493 | /** |
||
494 | * Get the last value from an array. |
||
495 | * |
||
496 | * @param int|null $take |
||
497 | * |
||
498 | * @return self |
||
499 | */ |
||
500 | 10 | public function last($take = null) |
|
510 | |||
511 | /** |
||
512 | * Get everything but the last..$to items. |
||
513 | * |
||
514 | * @param int $to |
||
515 | * |
||
516 | * @return self |
||
517 | */ |
||
518 | 10 | public function initial($to = 1) |
|
524 | |||
525 | /** |
||
526 | * Get the last elements from index $from. |
||
527 | * |
||
528 | * @param int $from |
||
529 | * |
||
530 | * @return self |
||
531 | */ |
||
532 | 13 | public function rest($from = 1) |
|
536 | |||
537 | //////////////////////////////////////////////////////////////////// |
||
538 | ///////////////////////////// ACT UPON ///////////////////////////// |
||
539 | //////////////////////////////////////////////////////////////////// |
||
540 | |||
541 | /** |
||
542 | * Iterate over an array and execute a callback for each loop. |
||
543 | * |
||
544 | * @param \Closure $closure |
||
545 | * |
||
546 | * @return mixed |
||
547 | */ |
||
548 | 1 | View Code Duplication | public function at(\Closure $closure) |
558 | |||
559 | //////////////////////////////////////////////////////////////////// |
||
560 | ////////////////////////////// ALTER /////////////////////////////// |
||
561 | //////////////////////////////////////////////////////////////////// |
||
562 | |||
563 | /** |
||
564 | * Merge the new $array into the current array, replace already existing keys |
||
565 | * from the current array with the key,values from the new $array |
||
566 | * and create new indexes. |
||
567 | * |
||
568 | * @param array $array |
||
569 | * |
||
570 | * @return self |
||
571 | */ |
||
572 | 8 | public function mergeAppendNewIndex(array $array = array()) |
|
576 | |||
577 | /** |
||
578 | * Merge the current array into the new $array, replace already existing keys |
||
579 | * from new $array with the key,values from the current array |
||
580 | * and create new indexes. |
||
581 | * |
||
582 | * @param array $array |
||
583 | * |
||
584 | * @return self |
||
585 | */ |
||
586 | public function mergePrependNewIndex(array $array = array()) |
||
590 | |||
591 | /** |
||
592 | * Merge the new $array into the current array and |
||
593 | * keep keys and values from the current array. |
||
594 | * |
||
595 | * @param array $array |
||
596 | * |
||
597 | * @return self |
||
598 | */ |
||
599 | public function mergeAppendKeepIndex(array $array = array()) |
||
604 | |||
605 | /** |
||
606 | * Merge the the current array into the $array, keep keys and values from the new $array. |
||
607 | * |
||
608 | * @param array $array |
||
609 | * |
||
610 | * @return self |
||
611 | */ |
||
612 | public function mergePrependKeepIndex(array $array = array()) |
||
617 | |||
618 | /** |
||
619 | * Merge the new $array into the current array, keep keys from the current array |
||
620 | * and overwrite values with the new $array. |
||
621 | * |
||
622 | * @param $array |
||
623 | * |
||
624 | * @return self |
||
625 | */ |
||
626 | public function mergeReplaceAppend(array $array = array()) |
||
630 | |||
631 | /** |
||
632 | * Merge the the current array into the $array, keep keys from the new $array |
||
633 | * and overwrite values with the old from the current array. |
||
634 | * |
||
635 | * @param $array |
||
636 | * |
||
637 | * @return self |
||
638 | */ |
||
639 | public function mergeReplacePrepend(array $array = array()) |
||
643 | |||
644 | /** |
||
645 | * Return values that are only in the current array. |
||
646 | * |
||
647 | * @param array $array |
||
648 | * |
||
649 | * @return self |
||
650 | */ |
||
651 | public function diff(array $array = array()) |
||
655 | |||
656 | /** |
||
657 | * Return values that are only in the new $array. |
||
658 | * |
||
659 | * @param array $array |
||
660 | * |
||
661 | * @return self |
||
662 | */ |
||
663 | public function diffReverse(array $array = array()) |
||
667 | |||
668 | /** |
||
669 | * Replace a value in an array. |
||
670 | * |
||
671 | * @param string $search The string to replace |
||
672 | * @param string $replacement What to replace it with |
||
673 | * |
||
674 | * @return self |
||
675 | */ |
||
676 | 3 | public function replaceValue($search, $replacement = '') |
|
687 | |||
688 | /** |
||
689 | * Replace values in an array. |
||
690 | * |
||
691 | * @param string $search The string to replace |
||
692 | * @param string $replacement What to replace it with |
||
693 | * |
||
694 | 1 | * @return self |
|
695 | */ |
||
696 | 1 | public function replaceValues($search, $replacement = '') |
|
706 | |||
707 | /** |
||
708 | 20 | * Replace the keys in an array with another set. |
|
709 | * |
||
710 | 20 | * @param array $keys An array of keys matching the array's size |
|
711 | * |
||
712 | 20 | * @return self |
|
713 | 16 | */ |
|
714 | 20 | public function replaceKeys(array $keys) |
|
720 | |||
721 | /** |
||
722 | * Iterate over an array and modify the array's value. |
||
723 | * |
||
724 | 1 | * @param \Closure $closure |
|
725 | * |
||
726 | 1 | * @return array |
|
727 | */ |
||
728 | 1 | View Code Duplication | public function each(\Closure $closure) |
738 | |||
739 | /** |
||
740 | 8 | * Shuffle an array. |
|
741 | * |
||
742 | 8 | * @return self |
|
743 | 8 | */ |
|
744 | public function shuffle() |
||
752 | 7 | ||
753 | 7 | /** |
|
754 | 1 | * Sort an array by key. |
|
755 | * |
||
756 | * @param string $direction |
||
757 | 8 | * |
|
758 | * @return self |
||
759 | */ |
||
760 | public function sortKeys($direction = 'ASC') |
||
779 | 8 | ||
780 | /** |
||
781 | 8 | * Implodes an array. |
|
782 | * |
||
783 | * @param string $with What to implode it with |
||
784 | * |
||
785 | 8 | * @return string |
|
786 | */ |
||
787 | 8 | public function implode($with = '') |
|
791 | |||
792 | /** |
||
793 | * Find all items in an array that pass the truth test. |
||
794 | * |
||
795 | * @param null $closure |
||
796 | * |
||
797 | * @return self |
||
798 | 1 | */ |
|
799 | public function filter($closure = null) |
||
809 | 1 | ||
810 | /** |
||
811 | * Invoke a function on all of an array's values. |
||
812 | 1 | * |
|
813 | * @param mixed $callable |
||
814 | * @param array $arguments |
||
815 | * |
||
816 | * @return self |
||
817 | */ |
||
818 | public function invoke($callable, $arguments = array()) |
||
834 | |||
835 | /** |
||
836 | * Return all items that fail the truth test. |
||
837 | * |
||
838 | * @param \Closure $closure |
||
839 | * |
||
840 | 8 | * @return self |
|
841 | */ |
||
842 | 8 | View Code Duplication | public function reject(\Closure $closure) |
854 | 7 | ||
855 | /** |
||
856 | 7 | * Remove the first value from an array. |
|
857 | * |
||
858 | * @return self |
||
859 | */ |
||
860 | public function removeFirst() |
||
866 | 7 | ||
867 | /** |
||
868 | 7 | * Remove the last value from an array. |
|
869 | 7 | * |
|
870 | 6 | * @return self |
|
871 | 6 | */ |
|
872 | public function removeLast() |
||
878 | 7 | ||
879 | 7 | /** |
|
880 | 7 | * Removes a particular value from an array (numeric or associative). |
|
881 | * |
||
882 | 7 | * @param mixed $value |
|
883 | * |
||
884 | * @return self |
||
885 | */ |
||
886 | public function removeValue($value) |
||
904 | |||
905 | /** |
||
906 | 8 | * Prepend a value to an array. |
|
907 | * |
||
908 | 8 | * @param mixed $value |
|
909 | * |
||
910 | 8 | * @return self |
|
911 | */ |
||
912 | public function prepend($value) |
||
918 | 7 | ||
919 | /** |
||
920 | 7 | * Append a value to an array. |
|
921 | * |
||
922 | 7 | * @param mixed $value |
|
923 | * |
||
924 | * @return self |
||
925 | */ |
||
926 | public function append($value) |
||
932 | 7 | ||
933 | 7 | /** |
|
934 | 7 | * Return the array in the reverse order. |
|
935 | 6 | * |
|
936 | 6 | * @return self |
|
937 | 6 | */ |
|
938 | public function reverse() |
||
944 | 7 | ||
945 | /** |
||
946 | * duplicate free copy of an array |
||
947 | * |
||
948 | * @return self |
||
949 | */ |
||
950 | public function unique() |
||
966 | } |
||
967 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.