Completed
Push — master ( 10dbdd...dbaf7b )
by Simon
12s
created

Set::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * This file is part of the Set package.
5
 * For the full copyright information please view the LICENCE file that was
6
 * distributed with this package.
7
 *
8
 * @copyright Simon Deeley 2017
9
 */
10
11
namespace simondeeley;
12
13
use InvalidArgumentException;
14
use SplFixedArray;
15
use simondeeley\Type\Type;
16
use simondeeley\Type\SetType;
17
use simondeeley\Type\TypeEquality;
18
use simondeeley\ImmutableArrayTypeObject;
19
use simondeeley\Helpers\TypeEqualityHelperMethods;
20
21
/**
22
 * Set type object
23
 *
24
 * Implements a mathematical set in PHP. A mathematical set is an unordered list
25
 * of items where two lists are considered equal if both sets contain the same
26
 * items but not necessarily in the same order or in the same quantity. So, for
27
 * example:
28
 *      Set(1, 2, 3) === Set(3, 1, 2);
29
 *      Set(1, 2, 3) === Set(1, 2, 2, 3);
30
 * but
31
 *      Set(1, 2) !== Set(1, 2, 3);
32
 *
33
 * @author Simon Deeley <[email protected]>
34
 */
35
abstract class Set extends ImmutableArrayTypeObject implements SetType, TypeEquality
36
{
37
    use TypeEqualityHelperMethods;
38
39
    /**
40
     * @var SplFixedArray
41
     */
42
    protected $data;
43
44
    /**
45
     * Construct a new Set
46
     *
47
     * @final
48
     * @param mixed ...$items - accepts any number of items
49
     * @return void
50
     */
51 10
    final public function __construct(...$items)
52
    {
53 10
        $this->data = SplFixedArray::fromArray($items);
54 10
    }
55
56
    /**
57
     * Compare equality of two Sets
58
     *
59
     * @final
60
     * @param Type $set - The set to compare with
61
     * @param int $flags - Optional flags
62
     * @return bool
63
     * @throws InvalidArgumentException - thrown if $type is not of an instance
64
     *                                    of {@link Set}
65
     */
66 10
    final public function equals(Type $set, int $flags = TypeEquality::IGNORE_OBJECT_IDENTITY): bool
67
    {
68 10
        if (false === $set instanceof SetType) {
69
            throw new InvalidArgumentException(sprintf(
70
                'Cannot compare %s with %s as they are not of the same type',
71
                get_class($this),
72
                get_class($tuple)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tuple seems to be never defined.
Loading history...
73
            ));
74
        }
75
76 10
        return $this->isInArray($this->data->toArray(), $set->data->toArray())
0 ignored issues
show
Bug introduced by
Accessing data on the interface simondeeley\Type\SetType suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
77 10
            && $this->isInArray($set->data->toArray(), $this->data->toArray())
78 10
            && $this->isSameTypeAs($set, $flags)
79 10
            && $this->isSameObjectAs($set, $flags);
80
    }
81
82
    /**
83
     * Helper function for evaluate differences between two arrays
84
     *
85
     * @param array $first
86
     * @param array $second
87
     * @return bool
88
     */
89 10
    final private function isInArray(array $first, array $second): bool
90
    {
91 10
        foreach ($first as $item) {
92 10
            if (false === in_array($item, $second, true)) {
93 10
                return false;
94
            }
95
        }
96
97 6
        return true;
98
    }
99
100
    /**
101
     * Return the type of the object
102
     *
103
     * @return string
104
     */
105
    public static function getType(): string
106
    {
107
        return 'SET';
108
    }
109
}
110