Completed
Push — master ( 1e032b...d01fce )
by Nate
02:22
created

ArrayList::lastIndexOf()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 4
cts 4
cp 1
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
namespace Tebru\Collection;
8
9
use ArrayIterator;
10
use OutOfBoundsException;
11
12
/**
13
 * Class ArrayList
14
 *
15
 * Implements [@see ListInterface] and maintains an array of elements
16
 *
17
 * @author Nate Brunette <[email protected]>
18
 */
19
class ArrayList extends AbstractList
20
{
21
    /**
22
     * An array of elements
23
     *
24
     * @var array
25
     */
26
    protected $elements = [];
27
28
    /**
29
     * Constructor
30
     *
31
     * @param array $elements
32
     */
33 67
    public function __construct(array $elements = [])
34
    {
35 67
        $this->elements = array_values($elements);
36 67
    }
37
38
    /**
39
     * Ensure the element exists in the collection
40
     *
41
     * Returns true if the collection can contain duplicates,
42
     * and false if it cannot.
43
     *
44
     * @param mixed $element
45
     * @return bool
46
     */
47 47
    public function add($element): bool
48
    {
49 47
        $this->elements[] = $element;
50
51 47
        return true;
52
    }
53
54
    /**
55
     * Removes object if it exists
56
     *
57
     * Returns true if the element was removed
58
     *
59
     * @param mixed $element
60
     * @return bool
61
     */
62 8
    public function remove($element): bool
63
    {
64 8
        $index = $this->indexOf($element);
65
66 8
        if (-1 === $index) {
67 2
            return false;
68
        }
69
70 7
        array_splice($this->elements, $index, 1);
71
72 7
        return true;
73
    }
74
75
    /**
76
     * Removes all elements from a collection
77
     *
78
     * @return void
79
     */
80 1
    public function clear()
81
    {
82 1
        $this->elements = [];
83 1
    }
84
85
    /**
86
     * Returns an array of all elements in the collection
87
     *
88
     * @return array
89
     */
90 91
    public function toArray(): array
91
    {
92 91
        return $this->elements;
93
    }
94
95
    /**
96
     * Retrieve an external iterator
97
     *
98
     * @return ArrayIterator
99
     */
100 8
    public function getIterator(): ArrayIterator
101
    {
102 8
        return new ArrayIterator($this->elements);
103
    }
104
105
    /**
106
     * Insert element at the specified index
107
     *
108
     * @param int $index
109
     * @param mixed $element
110
     * @return void
111
     * @throws \OutOfBoundsException if the index doesn't exist
112
     */
113 6
    public function insert(int $index, $element)
114
    {
115 6
        $this->assertIndex($index);
116
117 5
        array_splice($this->elements, $index, 0, [$element]);
118 5
    }
119
120
    /**
121
     * Inserts all elements of a collection at index
122
     *
123
     * @param int $index
124
     * @param CollectionInterface $collection
125
     * @return bool
126
     * @throws \OutOfBoundsException if the index doesn't exist
127
     */
128 4
    public function insertAll(int $index, CollectionInterface $collection): bool
129
    {
130 4
        $this->assertIndex($index);
131
132 3
        $size = $this->count();
133 3
        array_splice($this->elements, $index, 0, $collection->toArray());
134
135 3
        return $size !== $this->count();
136
    }
137
138
    /**
139
     * Returns the element at the index
140
     *
141
     * @param int $index
142
     * @return mixed
143
     * @throws \OutOfBoundsException if the index doesn't exist
144
     */
145 13
    public function get(int $index)
146
    {
147 13
        if (!$this->has($index)) {
148 2
            throw new OutOfBoundsException(sprintf('Tried to access element at index "%s"', $index));
149
        }
150
151 11
        return $this->elements[$index];
152
    }
153
154
    /**
155
     * Returns true if an element exists at the index
156
     *
157
     * @param int $index
158
     * @return bool
159
     */
160 19
    public function has(int $index): bool
161
    {
162 19
        return array_key_exists($index, $this->elements);
163
    }
164
165
    /**
166
     * Removes the element at the specified index
167
     *
168
     * This returns the element that was previously at this index
169
     *
170
     * @param int $index
171
     * @return mixed
172
     * @throws \OutOfBoundsException if the index doesn't exist
173
     */
174 2
    public function removeAt(int $index)
175
    {
176 2
        $oldElement = $this->get($index);
177 1
        array_splice($this->elements, $index, 1);
178
179 1
        return $oldElement;
180
    }
181
182
    /**
183
     * Replace the element at the specified index
184
     *
185
     * Returns the element that was previously at this index
186
     *
187
     * @param int $index
188
     * @param mixed $element
189
     * @return mixed
190
     * @throws \OutOfBoundsException if the index doesn't exist
191
     */
192 3
    public function set(int $index, $element)
193
    {
194 3
        $this->assertIndex($index);
195
196 2
        $oldElement = null;
197 2
        if ($this->has($index)) {
198 1
            $oldElement = $this->get($index);
199
        }
200
201 2
        $this->elements[$index] = $element;
202
203 2
        return $oldElement;
204
    }
205
206
    /**
207
     * Assert the index is able to be inserted
208
     *
209
     * @param int $index
210
     * @return void
211
     * @throws \OutOfBoundsException If the index is less than 0 or greater than current size
212
     */
213 13
    protected function assertIndex(int $index)
214
    {
215 13
        if ($index < 0 || $index > $this->count()) {
216 3
            throw new OutOfBoundsException(sprintf('Element unable to be inserted at index "%s"', $index));
217
        }
218 10
    }
219
}
220