Skip to content

Commit eecf89f

Browse files
committed
Improve speed
1 parent 7961400 commit eecf89f

File tree

3 files changed

+71
-79
lines changed

3 files changed

+71
-79
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
/vendor/*
22
.idea/
3+
4+
Bench.php

src/Set.php

Lines changed: 45 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,24 @@ public function add($value): Set
4949
return $this;
5050
}
5151

52+
/**
53+
* Removes the element associated to the value.
54+
*
55+
* @param mixed $value The value to remove from the Set object
56+
* @return boolean
57+
*/
58+
public function delete($value): bool
59+
{
60+
$key = array_search($value, $this->getArrayCopy(), true);
61+
62+
if ($key !== false) {
63+
unset($this[$key]);
64+
return true;
65+
}
66+
67+
return false;
68+
}
69+
5270
/**
5371
* Removes all elements from the Set object. Returns the Set object.
5472
*
@@ -62,21 +80,14 @@ public function clear(): Set
6280
}
6381

6482
/**
65-
* Removes the element associated to the value.
83+
* Returns a boolean asserting whether an element is present with the given value in the Set object or not.
6684
*
67-
* @param mixed $value The value to remove from the Set object
85+
* @param mixed $value The value to check for.
6886
* @return boolean
6987
*/
70-
public function delete($value): bool
88+
public function has($value): bool
7189
{
72-
$key = array_search($value, $this->getArrayCopy(), true);
73-
74-
if ($key !== false) {
75-
unset($this[$key]);
76-
return true;
77-
}
78-
79-
return false;
90+
return array_search($value, $this->getArrayCopy(), true) !== false;
8091
}
8192

8293
/**
@@ -86,7 +97,7 @@ public function delete($value): bool
8697
*
8798
* @param callable $callback The callback function
8899
* The callback is called with argument 1 being the current iterated value
89-
* @param mixed $args Additional arguments to pass to the callback function
100+
* @param mixed $args Additional arguments to pass to the callback function
90101
* @return Set
91102
*/
92103
public function each(callable $callback, ...$args): Set
@@ -113,17 +124,6 @@ public function entries(): ArrayIterator
113124
return $this->getIterator();
114125
}
115126

116-
/**
117-
* Returns a boolean asserting whether an element is present with the given value in the Set object or not.
118-
*
119-
* @param mixed $value The value to check for.
120-
* @return boolean
121-
*/
122-
public function has($value): bool
123-
{
124-
return array_search($value, $this->getArrayCopy(), true) !== false;
125-
}
126-
127127
/**
128128
* Returns an array of the values values with the Set onject
129129
*
@@ -144,55 +144,41 @@ public function values(): array
144144
*/
145145
public function merge(Set $set): Set
146146
{
147-
$iterator = $set->entries();
148-
149-
// create a copy of $set
150147
$merged = new Set();
151148
$merged->exchangeArray($this->values());
152149

153-
// add values from $set if not present
154-
while ($iterator->valid()) {
155-
if (!$this->has($iterator->current())) {
156-
$merged->add($iterator->current());
150+
foreach ($set->values() as $value) {
151+
if (!$this->has($value)) {
152+
$merged->add($value);
157153
}
158-
$iterator->next();
159154
}
160155

161-
$iterator->rewind();
162-
163156
return $merged;
164157
}
165158

166159
/**
167-
* Returns a new Set containing all uncommon items between this and a given Set instance.
160+
* Returns a new Set containing values preset in this set, but not in another given set.
168161
*
169-
* @param Set $set
162+
* @param Set $set Set to compare against
170163
* @return Set
171-
* @todo This is not very efficient as it iterates both Sets completely
172164
*
173165
*/
174166
public function diff(Set $set): Set
175167
{
176-
$entries = $this->entries();
177-
$iterator = $set->entries();
178-
$intersect = new Set;
179-
180-
// check $set values
181-
while ($entries->valid()) {
182-
if (!$set->has($entries->current())) {
183-
$intersect->add($entries->current());
184-
}
168+
if ($this->size === 0) {
169+
return new Set();
170+
}
185171

186-
$entries->next();
172+
if ($set->size === 0) {
173+
return (new Set())->merge($this);
187174
}
188175

189-
// check $additionalSet values
190-
while ($iterator->valid()) {
191-
if (!$this->has($iterator->current())) {
192-
$intersect->add($iterator->current());
193-
}
176+
$intersect = new Set;
194177

195-
$iterator->next();
178+
foreach ($this->values() as $value) {
179+
if (!$set->has($value)) {
180+
$intersect->add($value);
181+
}
196182
}
197183

198184
return $intersect;
@@ -203,22 +189,17 @@ public function diff(Set $set): Set
203189
* All values should be present, but ordinality does not matter
204190
*
205191
* @param Set $set The Set to check against
206-
* @return bool Whether $set was a subset of $set
192+
* @return bool Whether $set was a subset of $set
207193
*/
208194
public function subset(Set $set): bool
209195
{
210-
$iterator = $set->entries();
211-
212196
// iterate through $set and return false is an uncommon value is present
213-
while ($iterator->valid()) {
214-
if (!$this->has($iterator->current())) {
197+
foreach ($set->values() as $value) {
198+
if (!$this->has($value)) {
215199
return false;
216200
}
217-
$iterator->next();
218201
}
219202

220-
$iterator->rewind();
221-
222203
return true;
223204
}
224205

@@ -230,16 +211,13 @@ public function subset(Set $set): bool
230211
*/
231212
public function intersect(Set $set): Set
232213
{
233-
$iterator = $set->entries();
234-
$intersect = new Set;
214+
$intersect = new Set();
235215

236-
while ($iterator->valid()) {
237-
if ($this->has($iterator->current())) {
238-
$intersect->add($iterator->current());
216+
foreach ($set->values() as $value) {
217+
if ($this->has($value)) {
218+
$intersect->add($value);
239219
}
240-
$iterator->next();
241220
}
242-
$iterator->rewind();
243221

244222
return $intersect;
245223
}

tests/SetTest.php

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ public function testAdd()
2121
{
2222
$set = new Set();
2323
$set->add('a');
24+
$this->assertSame(['a'], $set->values());
2425

25-
$expected = ['a'];
26-
$result = $set->values();
27-
28-
$this->assertSame($expected, $result);
26+
$set->add('a');
27+
$this->assertSame(['a'], $set->values());
2928
}
3029

3130
public function testDelete()
@@ -77,19 +76,32 @@ public function testDiffOnSameValues()
7776
}
7877

7978
public function testDiffOnDifferentValues()
79+
{
80+
$set = new Set(1, 2);
81+
$set2 = new Set(3, 4);
82+
83+
$result = $set->diff($set2);
84+
85+
$this->assertSame(2, $result->size);
86+
$this->assertSame([1,2], $result->values());
87+
}
88+
89+
public function testDiffOnEmptySet()
8090
{
8191
$set = new Set();
82-
$set->add(1);
83-
$set->add(2);
92+
$set2 = new Set(3, 4);
8493

85-
$set2 = new Set();
86-
$set2->add(3);
87-
$set2->add(4);
94+
$result = $set->diff($set2);
95+
$this->assertSame(0, $result->size);
96+
}
8897

89-
$expected = 4;
90-
$result = $set->diff($set2)->size;
98+
public function testDiffOnEmptyTargetSet()
99+
{
100+
$set = new Set(1,2);
101+
$set2 = new Set();
91102

92-
$this->assertSame($expected, $result);
103+
$result = $set->diff($set2);
104+
$this->assertSame(2, $result->size);
93105
}
94106

95107
public function testHas()

0 commit comments

Comments
 (0)