elements = self::sanitize($elements); } /** * Creates the union of A and B. */ public static function union(Set $a, Set $b) : Set { return new self(array_merge($a->toArray(), $b->toArray())); } /** * Creates the intersection of A and B. */ public static function intersection(Set $a, Set $b) : Set { return new self(array_intersect($a->toArray(), $b->toArray())); } /** * Creates the difference of A and B. */ public static function difference(Set $a, Set $b) : Set { return new self(array_diff($a->toArray(), $b->toArray())); } /** * Creates the Cartesian product of A and B. * * @return Set[] */ public static function cartesian(Set $a, Set $b) : array { $cartesian = []; foreach ($a as $multiplier) { foreach ($b as $multiplicand) { $cartesian[] = new self(array_merge([$multiplicand], [$multiplier])); } } return $cartesian; } /** * Creates the power set of A. * * @return Set[] */ public static function power(Set $a) : array { $power = [new self()]; foreach ($a as $multiplicand) { foreach ($power as $multiplier) { $power[] = new self(array_merge([$multiplicand], $multiplier->toArray())); } } return $power; } /** * Removes duplicates and rewrites index. * * @param string[]|int[]|float[] $elements * * @return string[]|int[]|float[] */ private static function sanitize(array $elements) : array { sort($elements, SORT_ASC); return array_values(array_unique($elements, SORT_ASC)); } /** * @param string|int|float $element */ public function add($element) : Set { return $this->addAll([$element]); } /** * @param string[]|int[]|float[] $elements */ public function addAll(array $elements) : Set { $this->elements = self::sanitize(array_merge($this->elements, $elements)); return $this; } /** * @param string|int|float $element */ public function remove($element) : Set { return $this->removeAll([$element]); } /** * @param string[]|int[]|float[] $elements */ public function removeAll(array $elements) : Set { $this->elements = self::sanitize(array_diff($this->elements, $elements)); return $this; } /** * @param string|int|float $element */ public function contains($element) : bool { return $this->containsAll([$element]); } /** * @param string[]|int[]|float[] $elements */ public function containsAll(array $elements) : bool { return !array_diff($elements, $this->elements); } /** * @return string[]|int[]|float[] */ public function toArray() : array { return $this->elements; } public function getIterator() : \ArrayIterator { return new \ArrayIterator($this->elements); } public function isEmpty() : bool { return $this->cardinality() == 0; } public function cardinality() : int { return count($this->elements); } }