Arrays::compare()   B
last analyzed

Complexity

Conditions 11
Paths 8

Size

Total Lines 44
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 11.0077

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 11
eloc 27
c 2
b 0
f 0
nc 8
nop 2
dl 0
loc 44
ccs 24
cts 25
cp 0.96
crap 11.0077
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * PHP: Nelson Martell Library file
5
 *
6
 * Copyright © 2021 Nelson Martell (http://nelson6e65.github.io)
7
 *
8
 * Licensed under The MIT License (MIT)
9
 * For full copyright and license information, please see the LICENSE
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @copyright 2021 Nelson Martell
13
 * @link      http://nelson6e65.github.io/php_nml/
14
 * @since     1.0.0
15
 * @license   http://www.opensource.org/licenses/mit-license.php The MIT License (MIT)
16
 * */
17
18
namespace NelsonMartell\Extensions;
19
20
use InvalidArgumentException;
21
use NelsonMartell\IComparer;
22
use NelsonMartell\StrictObject;
23
24
use function NelsonMartell\msg;
25
use function NelsonMartell\typeof;
26
27
/**
28
 * Provides extension methods to handle arrays.
29
 *
30
 * @since 1.0.0
31
 * @author Nelson Martell <[email protected]>
32
 * */
33
class Arrays implements IComparer
34
{
35
    /**
36
     * Ensures that object given is an `array`. Else, throw an exception.
37
     *
38
     * @param mixed $obj Object to validate.
39
     *
40
     * @return array Same object given.
41
     *
42
     * @throws InvalidArgumentException if object is not an `array`.
43
     */
44
    public static function ensureIsArray($obj)
45
    {
46
        if (!is_array($obj)) {
47
            $msg = msg('Provided object must to be an array; "{0}" given.', typeof($obj));
48
            throw new InvalidArgumentException($msg);
49
        }
50
51
        return $obj;
52
    }
53
54
    /**
55
     * {@inheritDoc}
56
     *
57
     * This methods is specific for the case when one of them are `array`. In other case, will fallback to
58
     * `Objects::compare()`.` You should use it directly instead of this method as comparation function
59
     * for `usort()`.
60
     *
61
     * @param array|mixed $left
62
     * @param array|mixed $right
63
     *
64
     * @return int|null Returns null if one of them is not an `array`.
65
     *
66
     * @since 1.0.0  Move implementation of array comparation from `Objects::compare()`.
67
     * @see Objects::compare()
68
     */
69 12
    public static function compare($left, $right)
70
    {
71 12
        if (is_array($left)) {
72 12
            if (is_array($right)) {
73 8
                $r = count($left) - count($right);
74
75 8
                if ($r === 0) {
76
                    do {
77 4
                        $lKey   = array_key_first($left);
78 4
                        $lValue = current($left);
79 4
                        $rKey   = array_key_first($right);
80 4
                        $rValue = current($right);
81
82 4
                        $r = Objects::compare((string) $lKey, (string) $rKey);
83
84 4
                        if ($r === 0) {
85
                            // Recursive call to compare values
86 3
                            $r = Objects::compare($lValue, $rValue);
87
                        }
88
89 4
                        next($left);
90 4
                        next($right);
91 4
                    } while (key($left) !== null && key($right) !== null && $r === 0);
92
                }
93
94 8
                return $r;
95
            } else {
96 4
                if (typeof($right)->isCustom()) {
97 2
                    return -1;
98
                } else {
99 2
                    return 1;
100
                }
101
            }
102 2
        } elseif (is_array($right)) {
103 2
            $r = static::compare($right, $left);
104
105 2
            if ($r !== null) {
106 2
                $r *= -1; // Invert result
107
            }
108
109 2
            return $r;
110
        }
111
112
        return Objects::compare($left, $right);
113
    }
114
}
115