Passed
Push — master ( ede5c4...d0b3a2 )
by Max
02:45
created

ArrayList::first()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A ArrayList::get() 0 3 1
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 19
    public function add($value): void
27
    {
28 19
        $data = $this->toArray();
29
30 19
        array_push($data, $value);
31 19
        $this->dataHolder->setContainer($data);
32 19
    }
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 (!is_a($newArrayList, self::class)) {
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
     * Returns all the coincidences found
62
     * for the given callback or null.
63
     *
64
     * @param callable $callback
65
     *
66
     * @return \PHPCollections\Collections\ArrayList|null
67
     */
68 1
    public function filter(callable $callback): ?self
69
    {
70 1
        $matcheds = [];
71
72 1
        foreach ($this->dataHolder as $value) {
73 1
            if (call_user_func($callback, $value) === true) {
74 1
                $matcheds[] = $value;
75
            }
76
        }
77
78 1
        return count($matcheds) > 0 ? new $this(array_values($matcheds)) : null;
79
    }
80
81
    /**
82
     * Iterates over every element of the collection.
83
     *
84
     * @param callable $callback
85
     *
86
     * @return void
87
     */
88 1
    public function forEach(callable $callback): void
89
    {
90 1
        $data = $this->toArray();
91
92 1
        array_walk($data, $callback);
93 1
        $this->dataHolder->setContainer($data);
94 1
    }
95
96
    /**
97
     * Gets the element specified
98
     * at the given index.
99
     *
100
     * @param int $offset
101
     *
102
     * @return mixed
103
     */
104 5
    public function get(int $offset)
105
    {
106 5
        return $this->dataHolder->offsetGet($offset);
107
    }
108
109
    /**
110
     * Updates elements in the collection by
111
     * applying a given callback function.
112
     *
113
     * @param callable $callback
114
     *
115
     * @return \PHPCollections\Collections\ArrayList|null
116
     */
117 1
    public function map(callable $callback): ?self
118
    {
119 1
        $matcheds = array_map($callback, $this->toArray());
120
121 1
        return count($matcheds) > 0 ? new $this(array_values($matcheds)) : null;
122
    }
123
124
    /**
125
     * Merges two ArrayList into a new one.
126
     *
127
     * @param \PHPCollections\Collections\ArrayList $newArrayList
128
     *
129
     * @return \PHPCollections\Collections\ArrayList
130
     */
131 1
    public function merge(BaseCollection $newArrayList): BaseCollection
132
    {
133 1
        return new $this(array_merge($this->toArray(), $newArrayList->toArray()));
134
    }
135
136
    /**
137
     * Returns a random element of
138
     * the collection.
139
     *
140
     * @throws \PHPCollections\Exceptions\InvalidOperationException
141
     *
142
     * @return mixed
143
     */
144 1
    public function rand()
145
    {
146 1
        if ($this->isEmpty()) {
147 1
            throw new InvalidOperationException('You cannot get a random element from an empty collection');
148
        }
149
150
        $randomIndex = array_rand($this->toArray());
151
152
        return $this->get($randomIndex);
153
    }
154
155
    /**
156
     * Removes an item from the collection
157
     * and repopulates the data array.
158
     *
159
     * @param int $offset
160
     *
161
     * @throws \OutOfRangeException
162
     *
163
     * @return void
164
     */
165 1
    public function remove(int $offset): void
166
    {
167 1
        if ($this->isEmpty()) {
168
            throw new OutOfRangeException('You\'re trying to remove data from an empty collection');
169
        }
170
171 1
        if (!$this->dataHolder->offsetExists($offset)) {
172 1
            throw new OutOfRangeException(sprintf('The %d index does not exists for this collection', $offset));
173
        }
174
175 1
        $this->dataHolder->offsetUnset($offset);
176 1
    }
177
178
    /**
179
     * Returns a new collection with the
180
     * reversed values.
181
     *
182
     * @throws \PHPCollections\Exceptions\InvalidOperationException
183
     *
184
     * @return \PHPCollections\Collections\ArrayList
185
     */
186 2
    public function reverse(): self
187
    {
188 2
        if ($this->isEmpty()) {
189 1
            throw new InvalidOperationException('You cannot reverse an empty collection');
190
        }
191
192 1
        return new $this(array_reverse($this->toArray()));
193
    }
194
195
    /**
196
     * Returns a portion of the ArrayList.
197
     *
198
     * @param int      $offset
199
     * @param int|null $length
200
     *
201
     * @return PHPCollections\Collections\ArrayList|null
0 ignored issues
show
Bug introduced by
The type PHPCollections\Collectio...s\Collections\ArrayList was not found. Did you mean PHPCollections\Collections\ArrayList? If so, make sure to prefix the type with \.
Loading history...
202
     */
203 1
    public function slice(int $offset, ?int $length = null): ?BaseCollection
204
    {
205 1
        $newData = array_slice($this->toArray(), $offset, $length);
206
207 1
        return count($newData) > 0 ? new self($newData) : null;
0 ignored issues
show
Bug Best Practice introduced by
The expression return count($newData) >...w self($newData) : null also could return the type PHPCollections\Collections\ArrayList which is incompatible with the documented return type PHPCollections\Collectio...lections\ArrayList|null.
Loading history...
208
    }
209
210
    /**
211
     * Returns a new ArrayList with the
212
     * values ordered by a given callback
213
     * if couldn't sort returns null.
214
     *
215
     * @param callable $callback
216
     *
217
     * @return \PHPCollections\Collections\ArrayList|null
218
     */
219
    public function sort(callable $callback): ?BaseCollection
220
    {
221
        $data = $this->toArray();
222
223
        return usort($data, $callback) ? new $this($data) : null;
224
    }
225
226
    /**
227
     * Updates the value of the element
228
     * at the given index.
229
     *
230
     * @param int   $index
231
     * @param mixed $value
232
     *
233
     * @return bool
234
     */
235 2
    public function update(int $index, $value): bool
236
    {
237 2
        if (!$this->exists($index)) {
238 1
            throw new InvalidOperationException('You cannot update a non-existent value');
239
        }
240
241 1
        $this->dataHolder->offsetSet($index, $value);
242
243 1
        return $this->dataHolder->offsetGet($index) === $value;
244
    }
245
}
246