Skip to content

Commit

Permalink
add group_by and sum_by functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Raffaello Pieri authored and Raffaello Pieri committed Apr 20, 2016
1 parent 82f3259 commit b296bb3
Showing 1 changed file with 33 additions and 6 deletions.
39 changes: 33 additions & 6 deletions src/FnDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,31 @@ private function fn_min_by(array $args)
return $this->reduce('min_by:1', $args[0], ['any'], $fn);
}

private function fn_group_by(array $args)
{
$this->validate('group_by', $args, [['array'], ['expression']]);
$expr = $this->wrapExpression('group_by:1', $args[1], ['number', 'string']);
$fn = function ($carry, $item) use ($expr) {
$key = $expr($item);
$carry[$key][] = $item;
return $carry;
};
return $this->reduce('group_by:1', $args[0], ['any'], $fn, []);
}

private function fn_sum_by(array $args)
{
$this->validate('sum_by', $args, [['array'], ['expression'], ['expression']]);
$groupExpr = $this->wrapExpression('sum_by:1', $args[1], ['number', 'string']);
$complementExpr = $this->wrapExpression('sum_by:1', $args[2], ['number', 'number']);
$fn = function ($carry, $item) use ($groupExpr, $complementExpr) {
$key = $groupExpr($item);
$carry[$key] = ($carry[$key] ?? 0) + $complementExpr($item);
return $carry;
};
return $this->reduce('sum_by:1', $args[0], ['any'], $fn, []);
}

private function fn_reverse(array $args)
{
$this->validate('reverse', $args, [['array', 'string']]);
Expand Down Expand Up @@ -351,14 +376,15 @@ private function validateSeq($from, array $types, $a, $b)
/**
* Reduces and validates an array of values to a single value using a fn.
*
* @param string $from String of function:argument_position
* @param array $values Values to reduce.
* @param array $types Array of valid value types.
* @param callable $reduce Reduce function that accepts ($carry, $item).
* @param string $from String of function:argument_position
* @param array $values Values to reduce.
* @param array $types Array of valid value types.
* @param callable $reduce Reduce function that accepts ($carry, $item).
* @param mixed|null $initial Value to use in as initial result or in case the result is empty
*
* @return mixed
*/
private function reduce($from, array $values, array $types, callable $reduce)
private function reduce($from, array $values, array $types, callable $reduce, $initial = null)
{
$i = -1;
return array_reduce(
Expand All @@ -368,7 +394,8 @@ function ($carry, $item) use ($from, $types, $reduce, &$i) {
$this->validateSeq($from, $types, $carry, $item);
}
return $reduce($carry, $item, $i);
}
},
$initial
);
}

Expand Down

0 comments on commit b296bb3

Please sign in to comment.