Этот сайт — моя персональная записная книжка. Интересны мне, по большей части, программирование, история и события из моей жизни.

Коммунистический массив

Я тут в мемах, которые кинули бывшие коллеги, увидел «коммунистическую сортировку» — она каждому присваивает среднее значение, и не смог пройти мимо. Написал «коммунистический массив»:

class CommunistArray extends \ArrayObject
{
    public function __construct(array $array = [])
    {
        parent::__construct(self::createCommunistArray($array));
    }

    public function offsetSet(mixed $key, mixed $value): void
    {
        parent::offsetSet($key, $value);
        $this->redistribute();
    }

    public function offsetUnset(mixed $key): void
    {
        $first = $this->getIterator()->key();

        if ($first !== null) {
            $this[$first] += $this[$key];
            parent::offsetUnset($key);
            $this->redistribute();
        }
    }

    private static function createCommunistArray(array $array): array
    {
        if ($array) {
            $avg = array_sum($array) / sizeof($array);
            return array_fill_keys(array_keys($array), $avg);
        }

        return [];
    }

    private function redistribute(): void
    {
        (void) $this->exchangeArray(self::createCommunistArray((array) $this));
    }
}

Он делает всех равными и перераспределяет блага автоматически:

$comrades = new CommunistArray([0b1, 0o0, 3e1, 0x45]);

print_r($comrades); # 25, 25, 25, 25

$comrades[2] = 4;
print_r($comrades); # 19.75, 19.75, 19.75, 19.75

unset($comrades[0]);
print_r($comrades); # 24.6875, 24.6875, 24.6875