Skip to content

Instantly share code, notes, and snippets.

@potfur
Created January 22, 2014 10:32
Show Gist options
  • Save potfur/8556591 to your computer and use it in GitHub Desktop.
Save potfur/8556591 to your computer and use it in GitHub Desktop.
simple map reduce
<?php
error_reporting(-1);
// reader
// reads n per call starting from last position til EOF
$offset = 0;
$reader = function ($n = 100) use (&$offset) {
$limit = $offset + $n;
$ln = 0;
$content = array();
$fp = fopen(__DIR__ . '/txt/data.txt', 'r');
while (($line = fgets($fp)) && $ln < $limit) {
$ln++;
if($ln < $offset) {
continue;
}
$content[$ln] = (int) trim($line);
}
fclose($fp);
$offset+=$n;
return $content;
};
// transformer
// calculates mediane from set block
$median = function ($block) {
sort($block);
$m = (int) floor(count($block) / 2);
return $m % 2 ? $block[$m] : ($block[$m] + $block[$m-1]) / 2;
};
// transformer
// calculates average value from set block
$average = function($block) {
return array_sum($block) / count($block);
};
// combiner
// adds transformer result to array
$combiner = function(array $data, $block) {
$data[] = $block;
return $data;
};
// reductor
// uses reader, transformer and combiner to reduce input data
function reductor($reader, $transformer, $combiner) {
if (!is_callable($reader)) {
throw new \InvalidArgumentException('Reader must be callable');
}
if (!is_callable($transformer)) {
throw new \InvalidArgumentException('Transformer must be callable');
}
if (!is_callable($combiner)) {
throw new \InvalidArgumentException('Combiner must be callable');
}
$data = array();
while ($block = $reader()) {
$block = $transformer($block);
$data = $combiner($data, $block);
}
return $data;
}
var_dump(reductor($reader, $median, $combiner));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment