Skip to content

Instantly share code, notes, and snippets.

@potfur
Created January 22, 2014 10:32

Revisions

  1. potfur created this gist Jan 22, 2014.
    74 changes: 74 additions & 0 deletions gistfile1.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,74 @@
    <?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));