Passed
Push — master ( 6392fd...5e4dda )
by Luke
09:02
created

Collection::hasValueAt()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 1
crap 2
1
<?php
2
namespace Noz\Collection;
3
4
use Countable;
5
use JsonSerializable;
6
use Iterator;
7
use ArrayAccess;
8
use RuntimeException;
9
10
/**
11
 * Nozavroni Collection
12
 */
13
class Collection implements ArrayAccess, Iterator, Countable, JsonSerializable
14
{
15
    /** @var array */
16
    protected $items;
17
18
    /**
19
     * Collection constructor.
20
     *
21
     * @param array $items
22
     */
23 31
    public function __construct(array $items = [])
24
    {
25 31
        $this->items = $items;
26 31
        $this->rewind();
27 31
    }
28
29
    /**
30
     * Generate a collection from an array of items.
31
     * I created this method so that it's possible to extend a collection more easily.
32
     *
33
     * @param array $items
34
     *
35
     * @return Collection
36
     */
37 8
    public static function factory(array $items = [])
38
    {
39 8
        return new Collection($items);
40
    }
41
42
    /**
43
     * Get collection as an array
44
     *
45
     * @return array
46
     */
47 10
    public function toArray()
48
    {
49 10
        return $this->items;
50
    }
51
52
    /**
53
     * Determine if collection has a given key
54
     *
55
     * @param mixed $key The key to look for
56
     *
57
     * @return bool
58
     */
59 18
    public function has($key)
60
    {
61 18
        return isset($this->items[$key]) || array_key_exists($key, $this->items);
62
    }
63
64
    /**
65
     * Does collection have item at position?
66
     *
67
     * Determine if collection has an item at a particular position (indexed from one).
68
     * Position can be positive and start from the beginning or it can be negative and
69
     * start from the end.
70
     *
71
     * @param int $position
72
     *
73
     * @return bool
74
     */
75 2
    public function hasValueAt($position)
76
    {
77
        try {
78 2
            $this->getKeyAt($position);
79 2
            return true;
80 2
        } catch (RuntimeException $e) {
81 2
            return false;
82
        }
83
    }
84
85
    /**
86
     * Get key at given position
87
     *
88
     * Returns the key at the given position, starting from one. Position can be positive (start from beginning) or
89
     * negative (start from the end).
90
     *
91
     * If the position does not exist, a RuntimeException is thrown.
92
     *
93
     * @param int $position
94
     *
95
     * @return string
96
     *
97
     * @throws RuntimeException
98
     */
99 6
    public function getKeyAt($position)
100
    {
101 6
        $collection = $this;
102 6
        if ($position < 0) {
103 3
            $collection = $this->reverse();
104 3
        }
105 6
        $i = 1;
106 6
        foreach ($collection as $key => $val) {
107 6
            if (abs($position) == $i++) {
108 5
                return $key;
109
            }
110 6
        }
111 3
        throw new RuntimeException("No key at position {$position}");
112
    }
113
114
    /**
115
     * Get value at given position
116
     *
117
     * Returns the value at the given position, starting from one. Position can be positive (start from beginning) or
118
     * negative (start from the end).
119
     *
120
     * If the position does not exist, a RuntimeException is thrown.
121
     *
122
     * @param int $position
123
     *
124
     * @return mixed
125
     *
126
     * @throws RuntimeException
127
     */
128 2
    public function getValueAt($position)
129
    {
130 2
        return $this->get($this->getKeyAt($position));
131
    }
132
133
    /**
134
     * Get item by key, with an optional default return value
135
     *
136
     * @param mixed $key
137
     * @param mixed $default
138
     *
139
     * @return mixed
140
     */
141 7
    public function get($key, $default = null)
142
    {
143 7
        if ($this->has($key)) {
144 7
            return $this->items[$key];
145
        }
146
147 3
        return $default;
148
    }
149
150
    /**
151
     * Add an item with no regard to key
152
     *
153
     * @param mixed $value
154
     *
155
     * @return $this
156
     */
157 3
    public function add($value)
158
    {
159 3
        $this->items[] = $value;
160
161 3
        return $this;
162
    }
163
164
    /**
165
     * Set an item at a given key
166
     *
167
     * @param mixed $key
168
     * @param mixed $value
169
     *
170
     * @return $this
171
     */
172 3
    public function set($key, $value)
173
    {
174 3
        $this->items[$key] = $value;
175
176 3
        return $this;
177
    }
178
179
    /**
180
     * Delete an item by key
181
     *
182
     * @param mixed $key
183
     *
184
     * @return $this
185
     */
186 3
    public function delete($key)
187
    {
188 3
        unset($this->items[$key]);
189
190 3
        return $this;
191
    }
192
193
    /**
194
     * Clear the collection of all its items.
195
     *
196
     * @return $this
197
     */
198 1
    public function clear()
199
    {
200 1
        $this->items = [];
201
202 1
        return $this;
203
    }
204
205
    /**
206
     * Determine if collection contains given value
207
     *
208
     * @param mixed $val
209
     *
210
     * @return bool
211
     */
212 1
    public function contains($val)
213
    {
214 1
        return in_array($val, $this->items, true);
215
    }
216
217
    /**
218
     * Fetch item from collection by key and remove it from collection
219
     *
220
     * @param mixed $key
221
     *
222
     * @return mixed
223
     */
224 1
    public function pull($key)
225
    {
226 1
        if ($this->has($key)) {
227 1
            $value = $this->get($key);
228 1
            $this->delete($key);
229 1
            return $value;
230
        }
231 1
    }
232
233
    /**
234
     * Join collection items using a delimiter
235
     *
236
     * @param string $delim
237
     *
238
     * @return string
239
     */
240 1
    public function join($delim = '')
241
    {
242 1
        return implode($delim, $this->items);
243
    }
244
245
    /**
246
     * Determine if collection has any items
247
     *
248
     * @return bool
249
     */
250 3
    public function isEmpty()
251
    {
252 3
        return $this->count() == 0;
253
    }
254
255
    /**
256
     * Get a collection of only this collection's values (without its keys)
257
     *
258
     * @return Collection
259
     */
260 1
    public function values()
261
    {
262 1
        return static::factory(array_values($this->items));
263
    }
264
265
    /**
266
     * Get a collection of only this collection's keys
267
     *
268
     * @return Collection
269
     */
270 1
    public function keys()
271
    {
272 1
        return static::factory(array_keys($this->items));
273
    }
274
275
    /**
276
     * Get a collection with order reversed
277
     *
278
     * @return Collection
279
     */
280 3
    public function reverse()
281
    {
282 3
        return static::factory(array_reverse($this->items));
283
    }
284
285
    /**
286
     * Get a collection with keys and values flipped
287
     *
288
     * @return Collection
289
     */
290 1
    public function flip()
291
    {
292 1
        $collection = static::factory();
293 1
        foreach ($this as $key => $val) {
294 1
            $collection->set($val, $key);
295 1
        }
296 1
        return $collection;
297
    }
298
299
    /**
300
     * Shuffle the order of this collection's values
301
     *
302
     * @return Collection
303
     */
304 1
    public function shuffle()
305
    {
306 1
        shuffle($this->items);
307 1
        return $this;
308
    }
309
310
    /**
311
     * Get a random value from the collection
312
     *
313
     * @return mixed
314
     */
315 1
    public function random()
316
    {
317 1
        return $this->getValueAt(rand(1, $this->count()));
318
    }
319
320
    /**
321
     * Sort the collection
322
     *
323
     * @param mixed $algo
324
     *
325
     * @return Collection
326
     */
327
    public function sort($algo = null)
0 ignored issues
show
Unused Code introduced by
The parameter $algo is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
328
    {
329
330
    }
331
332
    /**
333
     * Get a new collection with only distinct values
334
     *
335
     * @return Collection
336
     */
337
    public function distict()
338
    {
339
340
    }
341
342
    /**
343
     * Remove all duplicate values from collection in-place
344
     *
345
     * @return Collection
346
     */
347
    public function deduplicate()
348
    {
349
350
    }
351
352
    /** ++++                  ++++ **/
353
    /** ++ Interface Compliance ++ **/
354
    /** ++++                  ++++ **/
355
356
    /**
357
     * @return array
358
     */
359 1
    public function jsonSerialize()
360
    {
361 1
        return $this->toArray();
362
    }
363
364
    /** ++++                  ++++ **/
365
    /** ++ Array Access Methods ++ **/
366
    /** ++++                  ++++ **/
367
368
    /**
369
     * {@inheritDoc}
370
     */
371 1
    public function offsetExists($offset)
372
    {
373 1
        return $this->has($offset);
374
    }
375
376
    /**
377
     * {@inheritDoc}
378
     */
379 2
    public function offsetGet($offset)
380
    {
381 2
        if (!$this->has($offset)) {
382 1
            throw new RuntimeException("Unknown offset: {$offset}");
383
        }
384
385 1
        return $this->get($offset);
386
    }
387
388
    /**
389
     * {@inheritDoc}
390
     */
391 1
    public function offsetUnset($offset)
392
    {
393 1
        $this->delete($offset);
394 1
    }
395
396
    /**
397
     * {@inheritDoc}
398
     */
399 1
    public function offsetSet($offset, $value)
400
    {
401 1
        if (!isset($offset)) {
402 1
            $this->add($value);
403 1
        }
404
405 1
        $this->set($offset, $value);
406 1
    }
407
408
    /** ++++                  ++++ **/
409
    /** ++   Iterator Methods   ++ **/
410
    /** ++++                  ++++ **/
411
412
    /**
413
     * {@inheritDoc}
414
     */
415 8
    public function current()
416
    {
417 8
        return current($this->items);
418
    }
419
420
    /**
421
     * {@inheritDoc}
422
     */
423 8
    public function key()
424
    {
425 8
        return key($this->items);
426
    }
427
428
    /**
429
     * {@inheritDoc}
430
     */
431 8
    public function next()
432
    {
433 8
        return next($this->items);
434
    }
435
436
    /**
437
     * {@inheritDoc}
438
     */
439 31
    public function rewind()
440
    {
441 31
        reset($this->items);
442 31
    }
443
444
    /**
445
     * {@inheritDoc}
446
     */
447 8
    public function valid()
448
    {
449 8
        return $this->has(key($this->items));
450
    }
451
452
    /** ++++                  ++++ **/
453
    /** ++   Countable Method   ++ **/
454
    /** ++++                  ++++ **/
455
456
    /**
457
     * {@inheritDoc}
458
     */
459 5
    public function count()
460
    {
461 5
        return count($this->items);
462
    }
463
}