Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
A Functional Guide to
Cat Herding with PHP
Generators
The Filter/Map/Reduce Pattern for PHP
Generators
A Functional Guide to Cat Herding with PHP Generators
• Blog Post
http://markbakeruk.net/2016/01/19/a-functional-guide-to-...
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
<?xml version="1.0" encoding="ISO-8859-1"?>
<gpx version="1.1"
creat...
A Functional Guide to Cat Herding with PHP Generators
namespace GpxReader;
class GpxHandler {
protected $gpxReader;
public...
A Functional Guide to Cat Herding with PHP Generators
// Create our initial Generator to read the gpx file
$gpxReader = ne...
A Functional Guide to Cat Herding with PHP Generators
2015-03-02 07:59:35
latitude: 54.5132, longitude: -3.0448, elevation...
A Functional Guide to Cat Herding with PHP Generators
Cat Herding with PHP Generators – Filter
• A filter selects only a subset of values from the Traversable.
• The rules for ...
Cat Herding with PHP Generators – Filter
function notEmpty($value) {
return !empty($value);
}
/**
* Version of filter to u...
Cat Herding with PHP Generators – Filter
/**
* The `$flag` option (and the constants ARRAY_FILTER_USE_KEY and ARRAY_FILTER...
Cat Herding with PHP Generators – Filter
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGp...
Cat Herding with PHP Generators – Filter
// Iterate over the trackpoint set from the gpx file,
// displaying each point de...
A Functional Guide to Cat Herding with PHP Generators
2015-03-02 13:20:21
latitude: 54.4692 longitude: -2.9677 elevation: ...
Cat Herding with PHP Generators – Map
• A map is like a foreach loop that transforms each value in the
Traversable.
• Each...
Cat Herding with PHP Generators – Map
function map(Callable $callback, Traversable $iterator) {
foreach ($iterator as $key...
Cat Herding with PHP Generators – Map
namespace GpxReaderHelpers;
class DistanceCalculator {
public function setDistance(G...
Cat Herding with PHP Generators – Map
// Create our initial Generator to read the gpx file
$gpxReader = new GpxReaderGpxHa...
Cat Herding with PHP Generators – Map
// Iterate over the trackpoint set from the gpx file, mapping the distances as we go...
Cat Herding with PHP Generators – Map
2015-03-02 07:59:35
latitude: 54.5132 longitude: -3.0448 elevation: 0
distance from ...
Cat Herding with PHP Generators – Reduce
• A reduce aggregates all the values in the Traversable to a single value.
• A ca...
Cat Herding with PHP Generators – Reduce
function reduce(Traversable $iterator, Callable $callback, $initial = null) {
$re...
Cat Herding with PHP Generators – Reduce
// Reduce our trackpoint set from the gpx file (mapping the distance as we go)
//...
Cat Herding with PHP Generators – Map
Total distance travelled is 19.27 km
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
A Functional Guide to Cat Herding with PHP Generators
https://github.com/lstrojny/functional-php
A Functional Guide to Cat Herding with PHP Generators
No cats were forced to walk anywhere that they didn't want to go
dur...
A Functional Guide to Cat Herding with PHP Generators
?
Questions
Who am I?
Mark Baker
Design and Development Manager
InnovEd (Innovative Solutions for Education) Ltd
Coordinator and Devel...
Upcoming SlideShare
Loading in …5
×

A Functional Guide to Cat Herding with PHP Generators

638 views

Published on

A real world application for Cat Tracking, demonstrating the filter/map/reduce pattern with PHP Generators

Published in: Software
  • Be the first to comment

  • Be the first to like this

A Functional Guide to Cat Herding with PHP Generators

  1. 1. A Functional Guide to Cat Herding with PHP Generators The Filter/Map/Reduce Pattern for PHP Generators
  2. 2. A Functional Guide to Cat Herding with PHP Generators • Blog Post http://markbakeruk.net/2016/01/19/a-functional-guide-to-cat-herding-with- php-generators/ • Code Examples https://github.com/MarkBaker/GeneratorFunctionExamples
  3. 3. A Functional Guide to Cat Herding with PHP Generators
  4. 4. A Functional Guide to Cat Herding with PHP Generators
  5. 5. A Functional Guide to Cat Herding with PHP Generators <?xml version="1.0" encoding="ISO-8859-1"?> <gpx version="1.1" creator="Memory-Map 5.4.2.1089 http://www.memory-map.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.topografix.com/GPX/1/1" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"> <trk> <name>Wythburn</name> <type>Track</type> <trkseg> <trkpt lat="54.5131924947" lon="-3.0448236664"><time>2015-03-02T07:59:35Z</time></trkpt> <trkpt lat="54.5131921768" lon="-3.0450893323"><time>2015-03-02T08:00:31Z</time></trkpt> <trkpt lat="54.5131534894" lon="-3.0448548317"><ele>192</ele><time>2015-03- 02T08:00:51Z</time></trkpt> ... <trkpt lat="54.4399968465" lon="-2.9721705119"><ele>52</ele><time>2015-03- 02T14:50:49Z</time></trkpt> </trkseg> </trk> </gpx>
  6. 6. A Functional Guide to Cat Herding with PHP Generators namespace GpxReader; class GpxHandler { protected $gpxReader; public function __construct($gpxFilename) { $this->gpxReader = new XMLReader(); $this->gpxReader->open($gpxFilename); } public function getElements($elementType) { while ($this->gpxReader->read()) { if ($this->gpxReader->nodeType == XMLREADER::ELEMENT && $this->gpxReader->name == $elementType) { $doc = new DOMDocument('1.0', 'UTF-8'); $xml = simplexml_import_dom($doc->importNode($this->gpxReader->expand(), true)); $gpxAttributes = $this->readAttributes($this->gpxReader); $gpxElement = $this->readChildren($xml); $gpxElement->position = $gpxAttributes; yield $gpxElement->timestamp => $gpxElement; } } } }
  7. 7. A Functional Guide to Cat Herding with PHP Generators // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Iterate over the trackpoint set from the gpx file, // displaying each point detail in turn foreach ($gpxReader->getElements('trkpt') as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation ); }
  8. 8. A Functional Guide to Cat Herding with PHP Generators 2015-03-02 07:59:35 latitude: 54.5132, longitude: -3.0448, elevation: 0 2015-03-02 08:00:31 latitude: 54.5132, longitude: -3.0451, elevation: 0 2015-03-02 08:00:51 latitude: 54.5132, longitude: -3.0449, elevation: 192 ... 2015-03-02 14:50:39 latitude: 54.4392, longitude: -2.9714, elevation: 52 2015-03-02 14:50:49 latitude: 54.4400, longitude: -2.9722, elevation: 52
  9. 9. A Functional Guide to Cat Herding with PHP Generators
  10. 10. Cat Herding with PHP Generators – Filter • A filter selects only a subset of values from the Traversable. • The rules for filtering are defined in a callback function. • If no callback is provided, then only non-empty values are returned.
  11. 11. Cat Herding with PHP Generators – Filter function notEmpty($value) { return !empty($value); } /** * Version of filter to use with versions of PHP prior to 5.6.0, * without the `$flag` option * **/ function filter(Traversable $filter, Callable $callback = null) { if ($callback === null) { $callback = 'notEmpty'; } foreach ($filter as $key => $value) { if ($callback($value)) { yield $key => $value; } } }
  12. 12. Cat Herding with PHP Generators – Filter /** * The `$flag` option (and the constants ARRAY_FILTER_USE_KEY and ARRAY_FILTER_USE_BOTH) * were introduced in PHP 5.6.0 * **/ function filter(Traversable $filter, Callable $callback = null, $flag = 0) { if ($callback === null) { $callback = 'notEmpty'; } foreach ($filter as $key => $value) { switch($flag) { case ARRAY_FILTER_USE_KEY: if ($callback($key)) { yield $key => $value; } break; case ARRAY_FILTER_USE_BOTH: if ($callback($value, $key)) { yield $key => $value; } break; default: if ($callback($value)) { yield $key => $value; } break; } } }
  13. 13. Cat Herding with PHP Generators – Filter // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Define the date/time filter parameters $startTime = new DateTime('2015-03-02 13:20:00Z'); $endTime = new DateTime('2015-03-02 13:30:00Z'); // Create the filter callback with the date/time parameters we've just defined $timeFilter = function($timestamp) use ($startTime, $endTime) { return $timestamp >= $startTime && $timestamp <= $endTime; };
  14. 14. Cat Herding with PHP Generators – Filter // Iterate over the trackpoint set from the gpx file, // displaying each point detail in turn foreach (filter($gpxReader->getElements('trkpt'), $timeFilter, ARRAY_FILTER_USE_KEY) as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation ); }
  15. 15. A Functional Guide to Cat Herding with PHP Generators 2015-03-02 13:20:21 latitude: 54.4692 longitude: -2.9677 elevation: 634 2015-03-02 13:21:13 latitude: 54.4691 longitude: -2.9677 elevation: 628 2015-03-02 13:21:58 latitude: 54.4690 longitude: -2.9676 elevation: 621 ... 2015-03-02 13:29:47 latitude: 54.4658 longitude: -2.9673 elevation: 533 2015-03-02 13:29:58 latitude: 54.4657 longitude: -2.9674 elevation: 531
  16. 16. Cat Herding with PHP Generators – Map • A map is like a foreach loop that transforms each value in the Traversable. • Each input value is transformed into a new output value. • The rules for the transformation are defined in a callback function.
  17. 17. Cat Herding with PHP Generators – Map function map(Callable $callback, Traversable $iterator) { foreach ($iterator as $key => $value) { yield $key => $callback($value); } }
  18. 18. Cat Herding with PHP Generators – Map namespace GpxReaderHelpers; class DistanceCalculator { public function setDistance(GpxReaderGpxElement $point) { $point->distance = $this->calculateDistance($point); return $point; } }
  19. 19. Cat Herding with PHP Generators – Map // Create our initial Generator to read the gpx file $gpxReader = new GpxReaderGpxHandler($gpxFilename); // Set the mapper to calculate the distance between a trackpoint // and the previous trackpoint $distanceCalculator = new GpxReaderHelpersDistanceCalculator();
  20. 20. Cat Herding with PHP Generators – Map // Iterate over the trackpoint set from the gpx file, mapping the distances as we go, // displaying each point detail in turn foreach (map([$distanceCalculator, 'setDistance'], $gpxReader->getElements('trkpt')) as $time => $element) { printf( '%s' . PHP_EOL . ' latitude: %7.4f longitude: %7.4f elevation: %d' . PHP_EOL . ' distance from previous point: %5.2f m' . PHP_EOL, $time->format('Y-m-d H:i:s'), $element->position->latitude, $element->position->longitude, $element->elevation, $element->distance ); }
  21. 21. Cat Herding with PHP Generators – Map 2015-03-02 07:59:35 latitude: 54.5132 longitude: -3.0448 elevation: 0 distance from previous point: 0.00 m 2015-03-02 08:00:31 latitude: 54.5132 longitude: -3.0451 elevation: 0 distance from previous point: 17.15 m 2015-03-02 08:00:51 latitude: 54.5132 longitude: -3.0449 elevation: 192 distance from previous point: 15.74 m ... 2015-03-02 14:50:39 latitude: 54.4392 longitude: -2.9714 elevation: 52 distance from previous point: 98.87 m 2015-03-02 14:50:49 latitude: 54.4400 longitude: -2.9722 elevation: 52 distance from previous point: 106.70 m
  22. 22. Cat Herding with PHP Generators – Reduce • A reduce aggregates all the values in the Traversable to a single value. • A callback function determines the process for the aggregation.
  23. 23. Cat Herding with PHP Generators – Reduce function reduce(Traversable $iterator, Callable $callback, $initial = null) { $result = $initial; foreach($iterator as $value) { $result = $callback($result, $value); } return $result; }
  24. 24. Cat Herding with PHP Generators – Reduce // Reduce our trackpoint set from the gpx file (mapping the distance as we go) // and summing the results to calculate the total distance travelled $totalDistance = reduce( map([$distanceCalculator, 'setDistance'], $gpxReader->getElements('trkpt')), function($runningTotal, $value) { $runningTotal += $value->distance; return $runningTotal; }, 0.0 ); // Display the results of our reduce printf( 'Total distance travelled is %5.2f km' . PHP_EOL, $totalDistance / 1000 );
  25. 25. Cat Herding with PHP Generators – Map Total distance travelled is 19.27 km
  26. 26. A Functional Guide to Cat Herding with PHP Generators
  27. 27. A Functional Guide to Cat Herding with PHP Generators
  28. 28. A Functional Guide to Cat Herding with PHP Generators https://github.com/lstrojny/functional-php
  29. 29. A Functional Guide to Cat Herding with PHP Generators No cats were forced to walk anywhere that they didn't want to go during the writing of this presentation.
  30. 30. A Functional Guide to Cat Herding with PHP Generators ? Questions
  31. 31. Who am I? Mark Baker Design and Development Manager InnovEd (Innovative Solutions for Education) Ltd Coordinator and Developer of: Open Source PHPOffice library PHPExcel, PHPWord,PHPPowerPoint, PHPProject, PHPVisio Minor contributor to PHP core @Mark_Baker https://github.com/MarkBaker http://uk.linkedin.com/pub/mark-baker/b/572/171

×