src/Utils/Utils.php
public static function groupBy($traversable, callable $keyFn)
    {
        self::invariant(
            is_array($traversable) || $traversable instanceof Traversable,
            __METHOD__ . ' expects array or Traversable'
        );

        $grouped = [];
        foreach ($traversable as $key => $value) {
            $newKeys = (array) $keyFn($value, $key);
            foreach ($newKeys as $newKey) {
                $grouped[$newKey][] = $value;
            }
        }

        return $grouped;
    }
public static function groupBy($traversable, callable $keyFn)
    {
        self::invariant(
            is_array($traversable) || $traversable instanceof Traversable,
            __METHOD__ . ' expects array or Traversable'
        );

        $grouped = [];
        foreach ($traversable as $key => $value) {
            $newKeys = (array) $keyFn($value, $key);
            foreach ($newKeys as $newKey) {
                $grouped[$newKey][] = $value;
            }
        }

        return $grouped;
    }
Splits original traversable to several arrays with keys equal to $keyFn return

E.g. Utils::groupBy([1, 2, 3, 4, 5], function($value) {return $value % 3}) will output:
[
1 => [1, 4],
2 => [2, 5],
0 => [3],
]

$keyFn is also allowed to return array of keys. Then value will be added to all arrays with given keys

@param mixed[]|Traversable $traversable

@return mixed[]