Skip to content

Commit 1cf5e98

Browse files
committed
add expected foreach iterate approach in Map interface implementation class
1 parent 7f939e1 commit 1cf5e98

File tree

5 files changed

+133
-27
lines changed

5 files changed

+133
-27
lines changed

README.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,31 @@ $map->size(); // 0
761761

762762
```
763763

764+
765+
#### Traverse map in _foreach_ loop
766+
[[↑ Map]](#map)
767+
768+
Object of Map interface can iterated in *foreach* loop. In this case keys and values will be passed before ones. Key can be of any type except an array.
769+
770+
```php
771+
772+
use \WS\Utils\Collections\HashMap;
773+
774+
$map = new HashMap();
775+
776+
$map->put(new SplObjectStorage(), 1);
777+
$map->put(null, 2);
778+
$map->put(false, 3);
779+
$map->put(true, 4);
780+
$map->put(0, 5);
781+
782+
foreach($map as $key => $value) {
783+
var_export($key); // object of SplObjectStorage class| null| false| true| 0
784+
var_export($value); // 1 | 2 | 3 | 4 | 5
785+
}
786+
787+
```
788+
764789
## Collection factory
765790
[[↑ Up]](#php-collections)
766791

doc/README.ru.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ $queue->peek(); // RuntimeException
593593
- [*containsKey* – Признак наличия пары по ключу](#containskey---признак-наличия-пары-по-ключу)
594594
- [*containsValue* – Признак наличия пары по значению](#containsvalue---признак-наличия-пары-по-значению)
595595
- [*size* – Количество пар в карте](#size---количество-пар-в-карте)
596+
- [Обход объекта map при помощи цикла _foreach_](#обход-объекта-map-при-помощи-цикла-_foreach_)
596597

597598
#### _put_ - Добавление пары *ключ/значение*
598599
[[↑ Карта (Map)]](#карта-map)
@@ -761,6 +762,30 @@ $map->size(); // 0
761762

762763
```
763764

765+
#### Обход объекта map при помощи цикла _foreach_
766+
[[↑ Карта (Map)]](#карта-map)
767+
768+
Объект типа Map можно итерировать в цикле *foreach*. В этом случае ключи и значения будут оригинальные. Таким образом ключом может быть любой тип кроме массива.
769+
770+
```php
771+
772+
use \WS\Utils\Collections\HashMap;
773+
774+
$map = new HashMap();
775+
776+
$map->put(new SplObjectStorage(), 1);
777+
$map->put(null, 2);
778+
$map->put(false, 3);
779+
$map->put(true, 4);
780+
$map->put(0, 5);
781+
782+
foreach($map as $key => $value) {
783+
var_export($key); // object of SplObjectStorage class| null| false| true| 0
784+
var_export($value); // 1 | 2 | 3 | 4 | 5
785+
}
786+
787+
```
788+
764789
## Фабрика создания коллекции
765790
[[↑ В начало]](#PHP-Коллекции)
766791

src/WS/Utils/Collections/HashMap.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,25 @@ public function put($key, $value): bool
2222

2323
public function getIterator()
2424
{
25-
return new ArrayIterator(array_map(static function (MapEntry $entry) {
26-
return $entry->getValue();
27-
}, $this->entries));
25+
return new class($this->entries) extends ArrayIterator {
26+
private $entries;
27+
public function __construct(array $entries)
28+
{
29+
$hashToValueArray = array_map(static function (MapEntry $entry) {
30+
return $entry->getValue();
31+
}, $entries);
32+
parent::__construct($hashToValueArray);
33+
$this->entries = $entries;
34+
}
35+
36+
public function key()
37+
{
38+
$arrayKey = parent::key();
39+
/** @var MapEntry $entry */
40+
$entry = $this->entries[$arrayKey];
41+
return $entry->getKey();
42+
}
43+
};
2844
}
2945

3046
public function values(): Collection

tests/WS/Utils/Collections/HashMapTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class HashMapTest extends TestCase
1111
{
1212
use MapInterfaceTestTrait;
1313

14-
private function createInstance(): Map
14+
protected function createInstance(): Map
1515
{
1616
return new HashMap();
1717
}

tests/WS/Utils/Collections/MapInterfaceTestTrait.php

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@
1515
*/
1616
trait MapInterfaceTestTrait
1717
{
18+
abstract protected function createInstance(): Map;
19+
1820
/**
1921
* @test
2022
*/
2123
public function checkSameObjectAsKey(): void
2224
{
2325
$obj1 = $obj2 = new SplObjectStorage();
24-
/** @var $instance Map */
2526
$instance = $this->createInstance();
2627
$instance->put($obj1, null);
27-
$this->assertTrue($instance->containsKey($obj2));
28+
self::assertTrue($instance->containsKey($obj2));
2829

29-
$this->assertNull($instance->get($obj2));
30+
self::assertNull($instance->get($obj2));
3031
}
3132

3233
/**
@@ -44,7 +45,7 @@ public function checkCount(): void
4445

4546
$instance->remove(4);
4647

47-
$this->assertEquals(4, $instance->size());
48+
self::assertEquals(4, $instance->size());
4849
}
4950

5051
/**
@@ -59,8 +60,8 @@ public function iterate(): void
5960

6061
$i = 10;
6162
foreach ($instance as $k => $v) {
62-
$this->assertSame($k, $v - 1);
63-
$this->assertSame($i, $k);
63+
self::assertSame($k, $v - 1);
64+
self::assertSame($i, $k);
6465
$i++;
6566
}
6667
}
@@ -70,7 +71,6 @@ public function iterate(): void
7071
*/
7172
public function keySetGetting(): void
7273
{
73-
/** @var Map $instance */
7474
$instance = $this->createInstance();
7575
$instance->put(1,1);
7676
$instance->put(2,1);
@@ -83,15 +83,14 @@ public function keySetGetting(): void
8383

8484
$set = $instance->keys();
8585

86-
$this->assertEquals(4, $set->size());
86+
self::assertEquals(4, $set->size());
8787
}
8888

8989
/**
9090
* @test
9191
*/
9292
public function valuesGetting(): void
9393
{
94-
/** @var Map $instance */
9594
$instance = $this->createInstance();
9695
$instance->put(1,1);
9796
$instance->put(2,1);
@@ -104,7 +103,7 @@ public function valuesGetting(): void
104103

105104
$values = $instance->values();
106105

107-
$this->assertEquals(4, $values->size());
106+
self::assertEquals(4, $values->size());
108107
}
109108

110109
/**
@@ -121,9 +120,9 @@ public function hashCodeAwareChecking(): void
121120
$instance->put($o2, null);
122121
$instance->put($o3, null);
123122

124-
$this->assertTrue($instance->containsKey(new TestInteger(1)));
125-
$this->assertTrue($instance->containsKey(new TestInteger(2)));
126-
$this->assertTrue($instance->containsKey(new TestInteger(3)));
123+
self::assertTrue($instance->containsKey(new TestInteger(1)));
124+
self::assertTrue($instance->containsKey(new TestInteger(2)));
125+
self::assertTrue($instance->containsKey(new TestInteger(3)));
127126
}
128127

129128
/**
@@ -136,8 +135,8 @@ public function containsValueChecking(): void
136135
$instance->put(2, 2);
137136
$instance->put(3, 3);
138137

139-
$this->assertTrue($instance->containsValue(1));
140-
$this->assertFalse($instance->containsValue(4));
138+
self::assertTrue($instance->containsValue(1));
139+
self::assertFalse($instance->containsValue(4));
141140
}
142141

143142
/**
@@ -150,8 +149,8 @@ public function getting(): void
150149
$instance->put(2, 2);
151150
$instance->put(3, 3);
152151

153-
$this->assertNotNull($instance->get(1));
154-
$this->assertNull($instance->get(4));
152+
self::assertNotNull($instance->get(1));
153+
self::assertNull($instance->get(4));
155154
}
156155

157156
/**
@@ -164,9 +163,9 @@ public function usingSimpleArrayAsKey(): void
164163
$instance->put([1, 2, 3], 2);
165164
$instance->put([1, 3, 3], 3);
166165

167-
$this->assertEquals(2, $instance->size());
168-
$this->assertTrue($instance->containsKey([1, 2, 3]));
169-
$this->assertTrue($instance->containsKey([1, 3, 3]));
166+
self::assertEquals(2, $instance->size());
167+
self::assertTrue($instance->containsKey([1, 2, 3]));
168+
self::assertTrue($instance->containsKey([1, 3, 3]));
170169
}
171170

172171
/**
@@ -179,7 +178,7 @@ public function removingOfAbsent(): void
179178
$instance->put(2, 2);
180179
$instance->put(3, 3);
181180

182-
$this->assertFalse($instance->remove(4));
181+
self::assertFalse($instance->remove(4));
183182
}
184183

185184
/**
@@ -189,7 +188,7 @@ public function usingFunctionAsKey(): void
189188
{
190189
$instance = $this->createInstance();
191190
$instance->put(static function () {}, null);
192-
$this->assertFalse($instance->containsKey(static function () {}));
191+
self::assertFalse($instance->containsKey(static function () {}));
193192
}
194193

195194
/**
@@ -198,7 +197,6 @@ public function usingFunctionAsKey(): void
198197
public function unsupportedKeyType(): void
199198
{
200199
$this->expectException(Exception::class);
201-
/** @var Map $map */
202200
$map = $this->createInstance();
203201
$f = null;
204202
try {
@@ -210,4 +208,46 @@ public function unsupportedKeyType(): void
210208
throw $exception;
211209
}
212210
}
211+
212+
/**
213+
* @test
214+
*/
215+
public function foreachObjectKeyValueChecking(): void
216+
{
217+
$map = $this->createInstance();
218+
219+
$map->put(new SplObjectStorage(), 1);
220+
$map->put(new SplObjectStorage(), 2);
221+
$map->put(new SplObjectStorage(), 3);
222+
223+
foreach ($map as $splObjectStorage => $intValue) {
224+
self::assertThat($splObjectStorage, self::isInstanceOf(SplObjectStorage::class));
225+
}
226+
}
227+
228+
/**
229+
* @test
230+
*/
231+
public function foreachAnyKeyValueChecking(): void
232+
{
233+
$map = $this->createInstance();
234+
235+
$map->put(null, 1);
236+
$map->put(false, 2);
237+
$map->put(true, 3);
238+
239+
foreach ($map as $k => $int) {
240+
switch ($int) {
241+
case 1:
242+
self::assertThat($k, self::isNull());
243+
break;
244+
case 2:
245+
self::assertThat($k, self::isFalse());
246+
break;
247+
case 3:
248+
self::assertThat($k, self::isTrue());
249+
break;
250+
}
251+
}
252+
}
213253
}

0 commit comments

Comments
 (0)