Completed
Push — master ( 3c3d94...73c299 )
by Nate
02:10
created

HashSet   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 4
dl 0
loc 150
ccs 35
cts 35
cp 1
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A add() 0 11 2
A contains() 0 6 1
A clear() 0 4 1
A retainAllArray() 0 13 3
A remove() 0 8 1
A toArray() 0 4 1
A filter() 0 4 1
A getIterator() 0 4 1
A getKey() 0 4 1
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
namespace Tebru\Collection;
8
9
use ArrayIterator;
10
11
/**
12
 * Class HashSet
13
 *
14
 * An [@see SetInterface] backed by a [@see HashMap]
15
 *
16
 * @author Nate Brunette <[email protected]>
17
 */
18
class HashSet extends AbstractSet
19
{
20
    /**
21
     * The data storage
22
     *
23
     * @var MapInterface
24
     */
25
    protected $map;
26
27
    /**
28
     * Constructor
29
     *
30
     * Use [@see AbstractSet::add] to ensure uniqueness
31
     *
32
     * @param array $elements
33
     */
34 8
    public function __construct(array $elements = null)
35
    {
36 8
        $this->map = new HashMap();
37
38 8
        if (null !== $elements) {
39 7
            $this->addAllArray($elements);
40
        }
41 8
    }
42
43
    /**
44
     * Adds the element to the collection if it doesn't exist
45
     *
46
     * @param mixed $element
47
     * @return bool
48
     */
49 61
    public function add($element): bool
50
    {
51 61
        $key = $this->getKey($element);
52 61
        if ($this->contains($element)) {
53 3
            return false;
54
        }
55
56 61
        $this->map->put($key, $element);
57
58 61
        return true;
59
    }
60
61
    /**
62
     * Returns true if the collection contains element
63
     *
64
     * @param mixed $element
65
     * @return bool
66
     */
67 61
    public function contains($element): bool
68
    {
69 61
        $key = $this->getKey($element);
70
71 61
        return $this->map->containsKey($key);
72
    }
73
74
    /**
75
     * Removes all elements from a collection
76
     *
77
     * @return void
78
     */
79 2
    public function clear()
80
    {
81 2
        $this->map->clear();
82 2
    }
83
84
    /**
85
     * Remove all items from this collection that don't exist in specified array
86
     *
87
     * Returns true if the collection was modified
88
     *
89
     * @param array $collection
90
     * @return bool
91
     */
92
    public function retainAllArray(array $collection): bool
93
    {
94
        $collectionKeys = array_map(function ($element) { return $this->getKey($element); }, $collection);
95
96 8
        $size = $this->count();
97 8
        foreach ($this as $element) {
98 8
            if (!in_array($this->getKey($element), $collectionKeys, true)) {
99 8
                $this->remove($element);
100
            }
101
        }
102
103 8
        return $size !== $this->count();
104
    }
105
106
    /**
107
     * Removes object if it exists
108
     *
109
     * Returns true if the element was removed
110
     *
111
     * @param mixed $element
112
     * @return bool
113
     */
114 16
    public function remove($element): bool
115
    {
116 16
        $key = $this->getKey($element);
117 16
        $size = $this->map->count();
118 16
        $this->map->remove($key);
119
120 16
        return $size !== $this->map->count();
121
    }
122
123
    /**
124
     * Returns an array of all elements in the collection
125
     *
126
     * @return array
127
     */
128 59
    public function toArray(): array
129
    {
130 59
        return $this->map->values()->toArray();
131
    }
132
133
    /**
134
     * Filter the collection using closure
135
     *
136
     * The closure will get passed each element.  Returning true from the
137
     * closure will include that element in the new collection.
138
     *
139
     * @param callable $filter
140
     * @return CollectionInterface
141
     */
142 2
    public function filter(callable $filter): CollectionInterface
143
    {
144 2
        return new static(array_filter($this->toArray(), $filter));
145
    }
146
147
    /**
148
     * Retrieve an external iterator
149
     *
150
     * @return ArrayIterator
151
     */
152 16
    public function getIterator(): ArrayIterator
153
    {
154 16
        return new ArrayIterator($this->toArray());
155
    }
156
157
    /**
158
     * Return the key to use for the HashMap
159
     *
160
     * @param mixed $element
161
     * @return mixed
162
     */
163 33
    protected function getKey($element)
164
    {
165 33
        return $element;
166
    }
167
}
168