From 407441e8572c58c62897410000f8c2ba1c9c2c1f Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Sun, 28 Jul 2024 20:01:55 -0400 Subject: [PATCH] Add mapToArray to doc list --- src/DocumentList.php | 18 ++++++++++++++++++ .../postgresql/DocumentListTest.php | 11 +++++++++++ tests/integration/sqlite/DocumentListTest.php | 11 +++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/DocumentList.php b/src/DocumentList.php index 47bdace..c72ea7f 100644 --- a/src/DocumentList.php +++ b/src/DocumentList.php @@ -103,6 +103,24 @@ class DocumentList } } + /** + * Iterate the generator, extracting key/value pairs returned as an associative array + * + * @template TValue The type for the mapped value + * @param callable(TDoc): (int|string) $keyFunc The function to extract a key from the document + * @param callable(TDoc): TValue $valueFunc The function to extract a value from the document + * @return TValue[] An associative array of values, keyed by the extracted keys + * @throws DocumentException If this is called once the generator has been consumed + */ + public function mapToArray(callable $keyFunc, callable $valueFunc): array + { + $results = []; + foreach ($this->items() as $item) { + $results[$keyFunc($item)] = $valueFunc($item); + } + return $results; + } + /** * Ensure the statement is destroyed if the generator is not exhausted */ diff --git a/tests/integration/postgresql/DocumentListTest.php b/tests/integration/postgresql/DocumentListTest.php index 135e434..88154e5 100644 --- a/tests/integration/postgresql/DocumentListTest.php +++ b/tests/integration/postgresql/DocumentListTest.php @@ -113,4 +113,15 @@ class DocumentListTest extends TestCase $this->assertEquals('*** *** ***** **** ****', implode(' ', $splats), 'Iteration did not have the expected result'); } + + public function testMapToArraySucceeds(): void + { + $list = DocumentList::create(Query::selectFromTable(ThrowawayDb::TABLE), [], + new DocumentMapper(TestDocument::class)); + $this->assertNotNull($list, 'There should have been a document list created'); + $this->assertTrue($list->hasItems(), 'There should be items in the list'); + $lookup = $list->mapToArray(fn($it) => $it->id, fn($it) => $it->value); + $expected = ['one' => 'FIRST!', 'two' => 'another', 'three' => '', 'four' => 'purple', 'five' => 'purple']; + $this->assertEquals($expected, $lookup, 'The array was not mapped correctly'); + } } diff --git a/tests/integration/sqlite/DocumentListTest.php b/tests/integration/sqlite/DocumentListTest.php index 88623a0..8962d69 100644 --- a/tests/integration/sqlite/DocumentListTest.php +++ b/tests/integration/sqlite/DocumentListTest.php @@ -111,4 +111,15 @@ class DocumentListTest extends TestCase $this->assertEquals('*** *** ***** **** ****', implode(' ', $splats), 'Iteration did not have the expected result'); } + + public function testMapToArraySucceeds(): void + { + $list = DocumentList::create(Query::selectFromTable(ThrowawayDb::TABLE), [], + new DocumentMapper(TestDocument::class)); + $this->assertNotNull($list, 'There should have been a document list created'); + $this->assertTrue($list->hasItems(), 'There should be items in the list'); + $lookup = $list->mapToArray(fn($it) => $it->id, fn($it) => $it->value); + $expected = ['one' => 'FIRST!', 'two' => 'another', 'three' => '', 'four' => 'purple', 'five' => 'purple']; + $this->assertEquals($expected, $lookup, 'The array was not mapped correctly'); + } }