code: 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;
      }
docs: 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[]