ArrayList   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 243
Duplicated Lines 0 %

Test Coverage

Coverage 90.32%

Importance

Changes 0
Metric Value
wmc 28
eloc 47
dl 0
loc 243
ccs 56
cts 62
cp 0.9032
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A add() 0 6 1
A diff() 0 15 3
A sort() 0 5 2
A slice() 0 5 2
A rand() 0 9 2
A forEach() 0 6 1
A merge() 0 3 1
A remove() 0 11 3
A reverse() 0 7 2
A filter() 0 11 4
A update() 0 9 2
A map() 0 5 2
A get() 0 3 1
A equals() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PHPCollections\Collections;
6
7
use OutOfRangeException;
8
use PHPCollections\Exceptions\InvalidOperationException;
9
use PHPCollections\Interfaces\CollectionInterface;
10
use PHPCollections\Interfaces\IterableInterface;
11
use PHPCollections\Interfaces\MergeableInterface;
12
use PHPCollections\Interfaces\SortableInterface;
13
14
/**
15
 * A list of values of any type.
16
 */
17
class ArrayList extends BaseCollection implements CollectionInterface, IterableInterface, MergeableInterface, SortableInterface
18
{
19
    /**
20
     * Adds a new element to the collection.
21
     *
22
     * @param mixed $value
23
     *
24
     * @return void
25
     */
26 24
    public function add($value): void
27
    {
28 24
        $data = $this->toArray();
29
30 24
        array_push($data, $value);
31 24
        $this->dataHolder->setContainer($data);
32 24
    }
33
34
    /**
35
     * Gets the difference between two ArrayList.
36
     *
37
     * @param \PHPCollections\Collections\ArrayList $newArrayList
38
     *
39
     * @throws \PHPCollections\Exceptions\InvalidOperationException
40
     *
41
     * @return \PHPCollections\Collections\ArrayList
42
     */
43 2
    public function diff(BaseCollection $newArrayList): BaseCollection
44
    {
45 2
        if (!$newArrayList instanceof self) {
46 1
            throw new InvalidOperationException('You should only compare an ArrayList against another ArrayList');
47
        }
48
49
        $diffValues = array_udiff($this->toArray(), $newArrayList->toArray(), function ($firstValue, $secondValue) {
50 1
            if (gettype($firstValue) !== gettype($secondValue)) {
51 1
                return -1;
52
            }
53
54 1
            return $firstValue <=> $secondValue;
55 1
        });
56
57 1
        return new self($diffValues);
58
    }
59
60
    /**
61
     * Determines if two ArrayList objects are equal.
62
     *
63
     * @param \PHPCollections\Collections\ArrayList $newArrayList
64
     *
65
     * @return \PHPCollections\Collections\ArrayList
66
     */
67 2
    public function equals(BaseCollection $newArrayList): bool
68
    {
69 2
        if (!$newArrayList instanceof self) {
70 1
            throw new InvalidOperationException('You should only compare an ArrayList against another ArrayList');
71
        }
72
73 1
        return $this->toArray() == $newArrayList->toArray();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->toArray() ...newArrayList->toArray() returns the type boolean which is incompatible with the documented return type PHPCollections\Collections\ArrayList.
Loading history...
74
    }
75
76
    /**
77
     * Returns all the coincidences found
78
     * for the given callback or null.
79
     *
80
     * @param callable $callback
81
     *
82
     * @return \PHPCollections\Collections\ArrayList|null
83
     */
84 1
    public function filter(callable $callback): ?self
85
    {
86 1
        $matcheds = [];
87
88 1
        foreach ($this->dataHolder as $value) {
89 1
            if (call_user_func($callback, $value) === true) {
90 1
                $matcheds[] = $value;
91
            }
92
        }
93
94 1
        return count($matcheds) > 0 ? new $this(array_values($matcheds)) : null;
95
    }
96
97
    /**
98
     * Iterates over every element of the collection.
99
     *
100
     * @param callable $callback
101
     *
102
     * @return void
103
     */
104 1
    public function forEach(callable $callback): void
105
    {
106 1
        $data = $this->toArray();
107
108 1
        array_walk($data, $callback);
109 1
        $this->dataHolder->setContainer($data);
110 1
    }
111
112
    /**
113
     * Gets the element specified
114
     * at the given index.
115
     *
116
     * @param int $offset
117
     *
118
     * @return mixed
119
     */
120 5
    public function get(int $offset)
121
    {
122 5
        return $this->dataHolder->offsetGet($offset);
123
    }
124
125
    /**
126
     * Updates elements in the collection by
127
     * applying a given callback function.
128
     *
129
     * @param callable $callback
130
     *
131
     * @return \PHPCollections\Collections\ArrayList|null
132
     */
133 1
    public function map(callable $callback): ?self
134
    {
135 1
        $matcheds = array_map($callback, $this->toArray());
136
137 1
        return count($matcheds) > 0 ? new $this(array_values($matcheds)) : null;
138
    }
139
140
    /**
141
     * Merges two ArrayList into a new one.
142
     *
143
     * @param \PHPCollections\Collections\ArrayList $newArrayList
144
     *
145
     * @return \PHPCollections\Collections\ArrayList
146
     */
147 1
    public function merge(BaseCollection $newArrayList): BaseCollection
148
    {
149 1
        return new $this(array_merge($this->toArray(), $newArrayList->toArray()));
150
    }
151
152
    /**
153
     * Returns a random element of
154
     * the collection.
155
     *
156
     * @throws \PHPCollections\Exceptions\InvalidOperationException
157
     *
158
     * @return mixed
159
     */
160 1
    public function rand()
161
    {
162 1
        if ($this->isEmpty()) {
163 1
            throw new InvalidOperationException('You cannot get a random element from an empty collection');
164
        }
165
166
        $randomIndex = array_rand($this->toArray());
167
168
        return $this->get($randomIndex);
169
    }
170
171
    /**
172
     * Removes an item from the collection
173
     * and repopulates the data array.
174
     *
175
     * @param int $offset
176
     *
177
     * @throws \OutOfRangeException
178
     *
179
     * @return void
180
     */
181 1
    public function remove(int $offset): void
182
    {
183 1
        if ($this->isEmpty()) {
184
            throw new OutOfRangeException('You\'re trying to remove data from an empty collection');
185
        }
186
187 1
        if (!$this->dataHolder->offsetExists($offset)) {
188 1
            throw new OutOfRangeException(sprintf('The %d index does not exists for this collection', $offset));
189
        }
190
191 1
        $this->dataHolder->offsetUnset($offset);
192 1
    }
193
194
    /**
195
     * Returns a new collection with the
196
     * reversed values.
197
     *
198
     * @throws \PHPCollections\Exceptions\InvalidOperationException
199
     *
200
     * @return \PHPCollections\Collections\ArrayList
201
     */
202 2
    public function reverse(): self
203
    {
204 2
        if ($this->isEmpty()) {
205 1
            throw new InvalidOperationException('You cannot reverse an empty collection');
206
        }
207
208 1
        return new $this(array_reverse($this->toArray()));
209
    }
210
211
    /**
212
     * Returns a portion of the ArrayList.
213
     *
214
     * @param int      $offset
215
     * @param int|null $length
216
     *
217
     * @return \PHPCollections\Collections\ArrayList|null
218
     */
219 1
    public function slice(int $offset, ?int $length = null): ?BaseCollection
220
    {
221 1
        $newData = array_slice($this->toArray(), $offset, $length);
222
223 1
        return count($newData) > 0 ? new self($newData) : null;
224
    }
225
226
    /**
227
     * Returns a new ArrayList with the
228
     * values ordered by a given callback
229
     * if couldn't sort returns null.
230
     *
231
     * @param callable $callback
232
     *
233
     * @return \PHPCollections\Collections\ArrayList|null
234
     */
235
    public function sort(callable $callback): ?BaseCollection
236
    {
237
        $data = $this->toArray();
238
239
        return usort($data, $callback) ? new $this($data) : null;
240
    }
241
242
    /**
243
     * Updates the value of the element
244
     * at the given index.
245
     *
246
     * @param int   $index
247
     * @param mixed $value
248
     *
249
     * @return bool
250
     */
251 2
    public function update(int $index, $value): bool
252
    {
253 2
        if (!$this->exists($index)) {
254 1
            throw new InvalidOperationException('You cannot update a non-existent value');
255
        }
256
257 1
        $this->dataHolder->offsetSet($index, $value);
258
259 1
        return $this->dataHolder->offsetGet($index) === $value;
260
    }
261
}
262