Skip to content

Feature Aggregate

github-actions[bot] edited this page Jul 16, 2026 · 1 revision

📊 Агрегация и сортировка

← Возможности · Главная · Сравнение

Сведение коллекции к значению и упорядочивание: reduce/sum/avg/min/max/ median/mode, implode/join, sort/sortDesc/sortBy/sortByDesc/sortKeys*.

Принцип работы

Агрегаты принимают имя поля (через array_column — C-скорость) или callback. Нечисловой мусор игнорируется, а не превращается в нули; числовые строки приводятся без потери типа и точности ('1.5'1.5, '42'42, '1e2'100.0). avg считается через fdiv (безопасно для пустых после фильтра). sortBy — преобразование Шварца: ключ сортировки вычисляется один раз на элемент (n вызовов вместо n·log n в компараторе), сортирует C-реализация asort/arsort.

use CloudCastle\Collection\Collection;

$totals = Collection::make([150, 70, 220]);

$totals->sum();     // 440
$totals->avg();     // 146.66…
$totals->median();  // 150
$totals->min();     // 70

// По полю структур — через array_column
$orders->sum('total');
$orders->max('total');
$orders->mode('status'); // самые частые значения (коллекция)

// Нечисловое игнорируется, числовые строки — без потери типа
Collection::make([1, 'str', 2, null])->sum();  // 3
Collection::make(['1.5'])->median();           // 1.5 (float, не 1)

// reduce: с ключом или без (без ключа — C-реализация array_reduce)
$totals->reduce(fn ($carry, $v) => $carry + $v, 0);   // 440
$totals->reduce('max', 0);                            // 220 — строковый callable безопасен

// Сортировка
$orders->sortBy('total');          // по Шварцу
$orders->sortByDesc('total');
$totals->sort();                   // значения по возрастанию (ключи сохранены)
$config->sortKeys();

Плюсы

  • sum/avg по полю — быстрейшие среди аналогов (~12× vs illuminate).
  • sortBy по Шварцу — в ~2.4× быстрее illuminate на структурах.
  • median/mode встроены (у большинства аналогов их нет).
  • Честная типизация чисел: строка '1.5' не обрежется до 1.

Минусы

  • reduce с трёхпараметрическим callback (с ключом) идёт PHP-циклом — чуть медленнее C-пути; используйте два параметра, если ключ не нужен.

✅ Рекомендуется

  • Статистику по полю считать напрямую: sum('total'), а не pluck('total')->sum().
  • mode() для «самых частых» значений вместо ручного countBy + max.
  • Для убывания использовать sortByDesc('x'), а не sortBy('x')->reverse().

❌ Антипаттерны

  • avg() по полю с нечисловым мусором в ожидании нулей — мусор игнорируется, среднее считается по числовым значениям.
  • Сортировка компаратором fn ($a, $b) => $a['x'] <=> $b['x'] вместо sortBy('x') — медленнее и многословнее.

Clone this wiki locally