Skip to content

Commit 59fe265

Browse files
committed
Merge branch 'develop'
* develop: specify next release add Sequence::zip() Fix third value
2 parents 655bc14 + 1ddf307 commit 59fe265

9 files changed

+270
-1
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 4.5.0 - 2022-09-18
4+
5+
### Added
6+
7+
- `Innmind\Immutable\Sequence::zip()`
8+
39
## 4.4.0 - 2022-07-14
410

511
### Added

docs/MONOIDS.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Monoids describe a way to combine two values of a given type. A monoid contains an identity value that when combined with another value doesn't change its value. The combine operation has to be associative meaning `combine(a, combine(b, c))` is the same as `combine(combine(a, b), c)`.
44

5-
A simple monoid is an addition because adding `0` (the identity value) to any other integer won't change the value and `add(1, add(2, 3))` is the the same result as `add(add(1, 2), 6)` (both return 6).
5+
A simple monoid is an addition because adding `0` (the identity value) to any other integer won't change the value and `add(1, add(2, 3))` is the the same result as `add(add(1, 2), 3)` (both return 6).
66

77
This library comes with a few monoids:
88
- `Innmind\Immutable\Monoid\Concat` to append 2 instances of `Innmind\Immutable\Str` together

docs/SEQUENCE.md

+14
Original file line numberDiff line numberDiff line change
@@ -456,3 +456,17 @@ $result; // 10
456456
```
457457

458458
**Important**: for lasy sequences bear in mind that the values will be kept in memory while the first call to `->match` didn't return.
459+
460+
## `->zip()`
461+
462+
This method allows to merge 2 sequences into a new one by combining the values of the 2 into pairs.
463+
464+
```php
465+
$firnames = Sequence::of('John', 'Luke', 'James');
466+
$lastnames = Sequence::of('Doe', 'Skywalker', 'Kirk');
467+
468+
$pairs = $firnames
469+
->zip($lastnames)
470+
->toList();
471+
$pairs; // [['John', 'Doe'], ['Luke', 'Skywalker'], ['James', 'Kirk']]
472+
```

src/Sequence.php

+15
Original file line numberDiff line numberDiff line change
@@ -593,4 +593,19 @@ public function any(callable $predicate): bool
593593
static fn() => false,
594594
);
595595
}
596+
597+
/**
598+
* If both sequences are not of the same length it will stop when it has
599+
* reached the end of the shortest of the two
600+
*
601+
* @template S
602+
*
603+
* @param self<S> $sequence
604+
*
605+
* @return self<array{T, S}>
606+
*/
607+
public function zip(self $sequence): self
608+
{
609+
return new self($this->implementation->zip($sequence->implementation));
610+
}
596611
}

src/Sequence/Defer.php

+25
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,31 @@ public function match(callable $wrap, callable $match, callable $empty)
578578
);
579579
}
580580

581+
/**
582+
* @template S
583+
*
584+
* @param Implementation<S> $sequence
585+
*
586+
* @return Implementation<array{T, S}>
587+
*/
588+
public function zip(Implementation $sequence): Implementation
589+
{
590+
/** @var Implementation<array{T, S}> */
591+
return new self(
592+
(static function(\Iterator $self, \Iterator $other) {
593+
/** @var \Iterator<T> $self */
594+
foreach ($self as $value) {
595+
if (!$other->valid()) {
596+
return;
597+
}
598+
599+
yield [$value, $other->current()];
600+
$other->next();
601+
}
602+
})($this->values, $sequence->iterator()),
603+
);
604+
}
605+
581606
/**
582607
* @return Implementation<T>
583608
*/

src/Sequence/Implementation.php

+9
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,13 @@ public function find(callable $predicate): Maybe;
284284
* @return R
285285
*/
286286
public function match(callable $wrap, callable $match, callable $empty);
287+
288+
/**
289+
* @template S
290+
*
291+
* @param self<S> $sequence
292+
*
293+
* @return self<array{T, S}>
294+
*/
295+
public function zip(self $sequence): self;
287296
}

src/Sequence/Lazy.php

+29
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,35 @@ public function match(callable $wrap, callable $match, callable $empty)
648648
return (new Defer($generator))->match($wrap, $match, $empty);
649649
}
650650

651+
/**
652+
* @template S
653+
*
654+
* @param Implementation<S> $sequence
655+
*
656+
* @return Implementation<array{T, S}>
657+
*/
658+
public function zip(Implementation $sequence): Implementation
659+
{
660+
$values = $this->values;
661+
662+
/** @var Implementation<array{T, S}> */
663+
return new self(
664+
static function(callable $registerCleanup) use ($values, $sequence) {
665+
/** @var RegisterCleanup $registerCleanup */
666+
$other = self::open($sequence, $registerCleanup);
667+
668+
foreach ($values($registerCleanup) as $value) {
669+
if (!$other->valid()) {
670+
return;
671+
}
672+
673+
yield [$value, $other->current()];
674+
$other->next();
675+
}
676+
},
677+
);
678+
}
679+
651680
/**
652681
* @return Implementation<T>
653682
*/

src/Sequence/Primitive.php

+29
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,35 @@ public function match(callable $wrap, callable $match, callable $empty)
451451
);
452452
}
453453

454+
/**
455+
* @template S
456+
*
457+
* @param Implementation<S> $sequence
458+
*
459+
* @return Implementation<array{T, S}>
460+
*/
461+
public function zip(Implementation $sequence): Implementation
462+
{
463+
/** @var list<array{T, S}> */
464+
$values = [];
465+
$other = $sequence->iterator();
466+
467+
foreach ($this->iterator() as $value) {
468+
/** @psalm-suppress ImpureMethodCall */
469+
if (!$other->valid()) {
470+
break;
471+
}
472+
473+
/** @psalm-suppress ImpureMethodCall */
474+
$values[] = [$value, $other->current()];
475+
/** @psalm-suppress ImpureMethodCall */
476+
$other->next();
477+
}
478+
479+
/** @var Implementation<array{T, S}> */
480+
return new self($values);
481+
}
482+
454483
private function has(int $index): bool
455484
{
456485
return \array_key_exists($index, $this->values);

tests/SequenceTest.php

+142
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,148 @@ public function testFold()
833833
$this->assertSame('bazfoobar', $str->toString());
834834
}
835835

836+
public function testZip()
837+
{
838+
$zipped = Sequence::of(0, 1, 2, 3)->zip(
839+
Sequence::of('a', 'b', 'c', 'd'),
840+
);
841+
842+
$this->assertSame(
843+
[[0, 'a'], [1, 'b'], [2, 'c'], [3, 'd']],
844+
$zipped->toList(),
845+
);
846+
847+
$zipped = Sequence::defer((static function() {
848+
yield 0;
849+
yield 1;
850+
yield 2;
851+
yield 3;
852+
})())->zip(
853+
Sequence::defer((static function() {
854+
yield 'a';
855+
yield 'b';
856+
yield 'c';
857+
yield 'd';
858+
})()),
859+
);
860+
861+
$this->assertSame(
862+
[[0, 'a'], [1, 'b'], [2, 'c'], [3, 'd']],
863+
$zipped->toList(),
864+
);
865+
866+
$zipped = Sequence::lazy(static function() {
867+
yield 0;
868+
yield 1;
869+
yield 2;
870+
yield 3;
871+
})->zip(
872+
Sequence::lazy(static function() {
873+
yield 'a';
874+
yield 'b';
875+
yield 'c';
876+
yield 'd';
877+
}),
878+
);
879+
880+
$this->assertSame(
881+
[[0, 'a'], [1, 'b'], [2, 'c'], [3, 'd']],
882+
$zipped->toList(),
883+
);
884+
}
885+
886+
public function testZipOfDifferentLengths()
887+
{
888+
$zipped = Sequence::of(0, 1, 2)->zip(
889+
Sequence::of('a', 'b', 'c', 'd'),
890+
);
891+
892+
$this->assertSame(
893+
[[0, 'a'], [1, 'b'], [2, 'c']],
894+
$zipped->toList(),
895+
);
896+
$zipped = Sequence::of(0, 1, 2, 3)->zip(
897+
Sequence::of('a', 'b', 'c'),
898+
);
899+
900+
$this->assertSame(
901+
[[0, 'a'], [1, 'b'], [2, 'c']],
902+
$zipped->toList(),
903+
);
904+
905+
$zipped = Sequence::defer((static function() {
906+
yield 0;
907+
yield 1;
908+
yield 2;
909+
})())->zip(
910+
Sequence::defer((static function() {
911+
yield 'a';
912+
yield 'b';
913+
yield 'c';
914+
yield 'd';
915+
})()),
916+
);
917+
918+
$this->assertSame(
919+
[[0, 'a'], [1, 'b'], [2, 'c']],
920+
$zipped->toList(),
921+
);
922+
923+
$zipped = Sequence::defer((static function() {
924+
yield 0;
925+
yield 1;
926+
yield 2;
927+
yield 3;
928+
})())->zip(
929+
Sequence::defer((static function() {
930+
yield 'a';
931+
yield 'b';
932+
yield 'c';
933+
})()),
934+
);
935+
936+
$this->assertSame(
937+
[[0, 'a'], [1, 'b'], [2, 'c']],
938+
$zipped->toList(),
939+
);
940+
941+
$zipped = Sequence::lazy(static function() {
942+
yield 0;
943+
yield 1;
944+
yield 2;
945+
})->zip(
946+
Sequence::lazy(static function() {
947+
yield 'a';
948+
yield 'b';
949+
yield 'c';
950+
yield 'd';
951+
}),
952+
);
953+
954+
$this->assertSame(
955+
[[0, 'a'], [1, 'b'], [2, 'c']],
956+
$zipped->toList(),
957+
);
958+
959+
$zipped = Sequence::lazy(static function() {
960+
yield 0;
961+
yield 1;
962+
yield 2;
963+
yield 3;
964+
})->zip(
965+
Sequence::lazy(static function() {
966+
yield 'a';
967+
yield 'b';
968+
yield 'c';
969+
}),
970+
);
971+
972+
$this->assertSame(
973+
[[0, 'a'], [1, 'b'], [2, 'c']],
974+
$zipped->toList(),
975+
);
976+
}
977+
836978
public function get($map, $index)
837979
{
838980
return $map->get($index)->match(

0 commit comments

Comments
 (0)