Page MenuHomeDevCentral

D2551.id.diff
No OneTemporary

D2551.id.diff

diff --git a/omnitools/src/Collections/BaseCollection.php b/omnitools/src/Collections/BaseCollection.php
--- a/omnitools/src/Collections/BaseCollection.php
+++ b/omnitools/src/Collections/BaseCollection.php
@@ -11,6 +11,12 @@
public static abstract function from (iterable $items) : static;
+ ///
+ /// Constants
+ ///
+
+ const CB_ZERO_ARG = "Callback function should have at least one argument";
+
///
/// Getters
///
diff --git a/omnitools/src/Collections/HashMap.php b/omnitools/src/Collections/HashMap.php
--- a/omnitools/src/Collections/HashMap.php
+++ b/omnitools/src/Collections/HashMap.php
@@ -154,12 +154,10 @@
public function filter (callable $callable) : self {
$argc = (new CallableElement($callable))->countArguments();
if ($argc === 0) {
- throw new InvalidArgumentException(
- "Callback should have at least one argument"
- );
+ throw new InvalidArgumentException(self::CB_ZERO_ARG);
}
- $mode = (int)($argc > 1);
+ $mode = (int)($argc > 1);
return new self(
array_filter($this->map, $callable, $mode)
);
@@ -174,6 +172,38 @@
return new self($mappedMap);
}
+ public function mapValuesAndKeys (callable $callable) : self {
+ $argc = (new CallableElement($callable))->countArguments();
+
+ $newMap = [];
+ foreach ($this->map as $key => $value) {
+ [$newKey, $newValue] = match($argc) {
+ 0 => throw new InvalidArgumentException(self::CB_ZERO_ARG),
+ 1 => $callable($value),
+ default => $callable($key, $value),
+ };
+ $newMap[$newKey] = $newValue;
+ }
+
+ return new self($newMap);
+ }
+
+ public function flatMap (callable $callable) : self {
+ $argc = (new CallableElement($callable))->countArguments();
+
+ $newMap = new self;
+ foreach ($this->map as $key => $value) {
+ $toAdd = match($argc) {
+ 0 => throw new InvalidArgumentException(self::CB_ZERO_ARG),
+ 1 => $callable($value),
+ default => $callable($key, $value),
+ };
+ $newMap->update($toAdd);
+ }
+
+ return $newMap;
+ }
+
public function filterKeys (callable $callable) : self {
return new self(
array_filter($this->map, $callable, ARRAY_FILTER_USE_KEY)
diff --git a/omnitools/src/Collections/Vector.php b/omnitools/src/Collections/Vector.php
--- a/omnitools/src/Collections/Vector.php
+++ b/omnitools/src/Collections/Vector.php
@@ -202,6 +202,22 @@
return new self($mappedVector);
}
+ public function flatMap (callable $callable) : self {
+ $argc = (new CallableElement($callable))->countArguments();
+
+ $newMap = new self;
+ foreach ($this->items as $key => $value) {
+ $toAdd = match($argc) {
+ 0 => throw new InvalidArgumentException(self::CB_ZERO_ARG),
+ 1 => $callable($value),
+ default => $callable($key, $value),
+ };
+ $newMap->append($toAdd);
+ }
+
+ return $newMap;
+ }
+
public function filterKeys (callable $callable) : self {
return new self(
array_filter($this->items, $callable, ARRAY_FILTER_USE_KEY)
diff --git a/omnitools/tests/Collections/HashMapTest.php b/omnitools/tests/Collections/HashMapTest.php
--- a/omnitools/tests/Collections/HashMapTest.php
+++ b/omnitools/tests/Collections/HashMapTest.php
@@ -226,6 +226,114 @@
$this->assertEquals($expected, $actual);
}
+ public function testMapKeysAndValues () : void {
+ $callback = function ($civilization, $author) {
+ return [$author[0], "$author, $civilization"];
+ };
+
+ $expected = [
+ // Some sci-fi civilizations and author
+ "I" => "Iain Banks, The Culture",
+ "A" => "Ann Leckie, Radchaai Empire",
+ "L" => "Lois McMaster Bujold, Barrayar",
+ "U"=> "Ursula K. Le Guin, Hainish",
+ ];
+
+ $actual = $this->map->mapValuesAndKeys($callback)->toArray();
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testMapKeysAndValuesForVectors () : void {
+ $callback = function ($author) {
+ return [$author[0], "author:" . $author];
+ };
+
+ $expected = [
+ // Some sci-fi civilizations and author
+ "I" => "author:Iain Banks",
+ "A" => "author:Ann Leckie",
+ "L" => "author:Lois McMaster Bujold",
+ "U" => "author:Ursula K. Le Guin",
+ ];
+
+ $actual = $this->map->mapValuesAndKeys($callback)->toArray();
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testMapKeysAndValuesWithCallbackWithoutArgument() : void {
+ $this->expectException(InvalidArgumentException::class);
+
+ $callback = function () {};
+ $this->map->mapValuesAndKeys($callback);
+ }
+
+ public function testFlatMap(): void {
+ $callback = function ($key, $value) {
+ $items = explode(" ", $value);
+
+ foreach ($items as $item) {
+ yield $item => $key;
+ }
+ };
+
+ $expected = [
+ "Iain" => "The Culture",
+ "Banks" => "The Culture",
+
+ "Ann" => "Radchaai Empire",
+ "Leckie" => "Radchaai Empire",
+
+ "Lois" => "Barrayar",
+ "McMaster" => "Barrayar",
+ "Bujold" => "Barrayar",
+
+ "Ursula"=> "Hainish",
+ "K."=> "Hainish",
+ "Le"=> "Hainish",
+ "Guin"=> "Hainish",
+ ];
+
+ $actual = $this->map->flatMap($callback)->toArray();
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testFlatMapForVectors() : void {
+ $callback = function ($value) {
+ $items = explode(" ", $value);
+
+ foreach ($items as $item) {
+ yield $item => $value;
+ }
+ };
+
+ $expected = [
+ "Iain" => "Iain Banks",
+ "Banks" => "Iain Banks",
+
+ "Ann" => "Ann Leckie",
+ "Leckie" => "Ann Leckie",
+
+ "Lois" => "Lois McMaster Bujold",
+ "McMaster" => "Lois McMaster Bujold",
+ "Bujold" => "Lois McMaster Bujold",
+
+ "Ursula"=> "Ursula K. Le Guin",
+ "K."=> "Ursula K. Le Guin",
+ "Le"=> "Ursula K. Le Guin",
+ "Guin"=> "Ursula K. Le Guin",
+ ];
+
+ $actual = $this->map->flatMap($callback)->toArray();
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testFlatMapWithCallbackWithoutArgument() : void {
+ $this->expectException(InvalidArgumentException::class);
+
+ $callback = function () {};
+ $this->map->flatMap($callback);
+ }
+
public function testFilter () {
// Let's filter to keep names with 3 parts or more
diff --git a/omnitools/tests/Collections/VectorTest.php b/omnitools/tests/Collections/VectorTest.php
--- a/omnitools/tests/Collections/VectorTest.php
+++ b/omnitools/tests/Collections/VectorTest.php
@@ -120,6 +120,58 @@
}
+ public function testFlatMap () : void {
+ $expected = [
+ // Squares and cubes
+ 1, 1,
+ 4, 8,
+ 9, 27,
+ 16, 64,
+ 25, 125
+ ];
+
+ $callback = function ($n) {
+ yield $n * $n;
+ yield $n * $n * $n;
+ };
+
+ $actual = $this->vector->flatMap($callback)->toArray();
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testFlatMapWithKeyValueCallback() : void {
+ $vector = new Vector(["foo", "bar", "quux", "xizzy"]);
+
+ $callback = function (int $key, string $value) {
+ yield "$key::$value";
+ yield "$value ($key)";
+ };
+
+ $expected = [
+ "0::foo",
+ "foo (0)",
+
+ "1::bar",
+ "bar (1)",
+
+ "2::quux",
+ "quux (2)",
+
+ "3::xizzy",
+ "xizzy (3)",
+ ];
+
+ $actual = $vector->flatMap($callback)->toArray();
+ $this->assertEquals($expected, $actual);
+ }
+
+ public function testFlatMapWithCallbackWithoutArgument() : void {
+ $this->expectException(InvalidArgumentException::class);
+
+ $callback = function () {};
+ $this->vector->flatMap($callback);
+ }
+
public function testFilter () : void {
$vector = new Vector(["foo", "bar", "quux", "xizzy"]);

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 29, 09:31 (2 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2271043
Default Alt Text
D2551.id.diff (8 KB)

Event Timeline