Skip to content

Commit

Permalink
Merge pull request cakephp#17869 from cakephp/feature/5.1-map-reduce
Browse files Browse the repository at this point in the history
Allow specifying key when emitting intermediate value for MapReduce
  • Loading branch information
markstory authored Aug 27, 2024
2 parents ddd9dc7 + 58e7fb4 commit 910824d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
11 changes: 9 additions & 2 deletions src/Collection/Iterator/MapReduce.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,18 @@ public function getIterator(): Traversable
*
* @param mixed $val The record itself to store in the bucket
* @param mixed $bucket the name of the bucket where to put the record
* @param mixed $key An optional key to assign to the value
* @return void
*/
public function emitIntermediate(mixed $val, mixed $bucket): void
public function emitIntermediate(mixed $val, mixed $bucket, mixed $key = null): void
{
$this->_intermediate[$bucket][] = $val;
if ($key === null) {
$this->_intermediate[$bucket][] = $val;

return;
}

$this->_intermediate[$bucket][$key] = $val;
}

/**
Expand Down
26 changes: 26 additions & 0 deletions tests/TestCase/Collection/Iterator/MapReduceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,32 @@ public function testInvertedIndexCreation(): void
$this->assertEquals($expected, iterator_to_array($results));
}

public function testSpecifyingKeyWhenEmittingIntermediate(): void
{
$data = [
'document_1' => 'one two three',
'document_2' => 'one three',
'document_3' => 'two four',
];
$mapper = function ($row, $document, $mr): void {
$words = array_map('strtolower', explode(' ', $row));
foreach ($words as $word) {
$mr->emitIntermediate($document, $word, $document);
}
};
$reducer = function ($documents, $word, $mr): void {
$mr->emit(array_unique($documents), $word);
};
$results = new MapReduce(new ArrayIterator($data), $mapper, $reducer);
$expected = [
'one' => ['document_1' => 'document_1', 'document_2' => 'document_2'],
'two' => ['document_1' => 'document_1', 'document_3' => 'document_3'],
'three' => ['document_1' => 'document_1', 'document_2' => 'document_2'],
'four' => ['document_3' => 'document_3'],
];
$this->assertEquals($expected, iterator_to_array($results));
}

/**
* Tests that it is possible to use the emit function directly in the mapper
*/
Expand Down

0 comments on commit 910824d

Please sign in to comment.