Passed
Push — master ( adabb4...9c2afa )
by Maxim
58s queued 10s
created

HashMap.php$0 ➔ values()   A

Complexity

Conditions 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 2
crap 2
1
<?php
2
/**
3
 * @author Anton Lytkin <[email protected]>
4
 * @license MIT
5
 */
6
7
namespace WS\Utils\Collections;
8
9
use ArrayIterator;
10
use RuntimeException;
11
12
class HashMap implements Map
13
{
14
    private $entries = [];
15
16 42
    public function put($key, $value): bool
17
    {
18 42
        $this->entries[$this->getKeyHash($key)] = new MapEntry($key, $value);
19
20 41
        return true;
21
    }
22
23
    public function getIterator()
24
    {
25
        return new class($this->entries) extends ArrayIterator {
26
            private $entries;
27 3
            public function __construct(array $entries)
28
            {
29
                $hashToValueArray = array_map(static function (MapEntry $entry) {
30 3
                    return $entry->getValue();
31 3
                }, $entries);
32 3
                parent::__construct($hashToValueArray);
33 3
                $this->entries = $entries;
34 3
            }
35
36 3
            public function key()
37
            {
38 3
                $arrayKey = parent::key();
39
                /** @var MapEntry $entry */
40 3
                $entry = $this->entries[$arrayKey];
41 3
                return $entry->getKey();
42
            }
43
        };
44
    }
45
46 1
    public function values(): Collection
47
    {
48 1
        $values = [];
49
        /** @var MapEntry $entry */
50 1
        foreach ($this->entries as $entry) {
51 1
            $values[] = $entry->getValue();
52
        }
53 1
        return new ArrayList($values);
54
    }
55
56 11
    public function keys(): Collection
57
    {
58 11
        $keys = [];
59
        /** @var MapEntry $entry */
60 11
        foreach ($this->entries as $entry) {
61 10
            $keys[] = $entry->getKey();
62
        }
63 11
        return new ArrayList($keys);
64
    }
65
66
    /**
67
     * @param $key
68
     * @return string
69
     */
70 43
    private function getKeyHash($key): string
71
    {
72 43
        if (is_scalar($key)) {
73 31
            return $key.'';
74
        }
75 15
        if ($key instanceof HashCodeAware) {
76 6
            return $key->getHashCode();
77
        }
78 9
        if (is_object($key)) {
79 5
            return spl_object_hash($key);
80
        }
81 4
        if ($key === null) {
82 2
            return '__NULL__';
83
        }
84 2
        if (is_array($key)) {
85 1
            return md5(json_encode($key));
86
        }
87 1
        throw new RuntimeException("The type of $key is not supported");
88
    }
89
90 10
    public function remove($key): bool
91
    {
92 10
        $res = $this->containsKey($key);
93
94 10
        if (!$res) {
95 5
            return false;
96
        }
97 7
        unset($this->entries[$this->getKeyHash($key)]);
98 7
        return true;
99
    }
100
101
    /**
102
     * @inheritDoc
103
     */
104 25
    public function containsKey($key): bool
105
    {
106 25
        return isset($this->entries[$this->getKeyHash($key)]);
107
    }
108
109 20
    public function size(): int
110
    {
111 20
        return count($this->entries);
112
    }
113
114
    /**
115
     * @inheritDoc
116
     */
117 7
    public function get($key)
118
    {
119 7
        if (!$this->containsKey($key)) {
120 6
            return null;
121
        }
122
123 7
        $entry = $this->entries[$this->getKeyHash($key)];
124 7
        return $entry->getValue();
125
    }
126
127
    /**
128
     * @inheritDoc
129
     */
130 1
    public function containsValue($tested): bool
131
    {
132 1
        foreach ($this->entries as $entry) {
133 1
            if ($entry->getValue() === $tested) {
134 1
                return true;
135
            }
136
        }
137 1
        return false;
138
    }
139
140 1
    public function stream(): Stream
141
    {
142 1
        return new SerialStream(CollectionFactory::from(array_values($this->entries)));
143
    }
144
}
145