I've found myself on numerous occasions needing to with large text-files, where joining this on that, and filtering this out on arbitrary conditions.
The first couple of times, this turned into a loop in a loop in a loop mess which was indented more times than I care to either remember or admit.
More recently, I've attempted to make something that looks and behaves more "functional". Below is the basic class and a simple example.
I'm primarily concerned with extensibility. I'm not sure the approach I use will lend itself to extensibility in the future. I though, for example, about trying to stream results to disc, and I'm not sure that's doable at all without a fundamental change. Similarly it would be useful to add a simple ->not() for negating a filter, which I also don't see easily doable here.
A secondary concern is performance. PHP is perhaps not the best choice for a functional style. I'm guessing the performance of all these function calls isn't fantastic. Anything obvious I can do to improve it? If "real" performance is a requirement, the obvious suggestion might just to be to not use PHP, but if there are cheap ways to stretch this further, it would be nice.
Code:
class Functional {
protected $result;
protected $extra_data;
public function __construct($array = NULL) {
$this->result = $array;
}
public function reduce($callback, $i = NULL) {
if ($i === NULL) {
$i = $this->result;
}
$result = array_reduce($i, $callback);
$this->result = $result;
return $this;
}
public function walk($callback, $i = NULL) {
if ($i === NULL) {
$i = $this->result;
}
array_walk($i, $callback);
$this->result = $i;
return $this;
}
public function filter($callback, $i = NULL) {
if ($i === NULL) {
$i = $this->result;
}
$this->result = array_filter($i, $callback);
return $this;
}
public function result() {
return $this->result;
}
public function gather($callback, $key) {
$this->extra[$key] = $callback($this->result)
return $this;
}
public function extra($key) {
return $this->extra[$key];
}
}
Example usage:
$a = [1, 2, 3, 4];
$f = new Functional($a);
$result = $f->walk(function(&$i) { return $i *= 2; })
->reduce(function($i, $j) { return $i + $j; })
->result();
var_dump($result);
int(20)
callable
type-hint. All in all, I'd also say that you're taking a tool (PHP), and try to use it as something it's not (ie a functional language). You can sort of pull this off, but it's not the best thing to do, IMHO. Using JS, or Scheme, or Haskell would be my advice \$\endgroup\$$this->
be a part of functional programming? \$\endgroup\$