Collection::count()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Enzyme\Collection;
4
5
use Closure;
6
7
class Collection extends BaseCollection
8
{
9
    /**
10
     * Static helper method to instantiate a new collection. Useful for when you
11
     * want to immediately chain a method. Eg: Collection::make([1, 2, 3])->map(...).
12
     *
13
     * @param array $initial
14
     *
15
     * @return Collection
16
     */
17
    public static function make(array $initial)
18
    {
19
        return new static($initial);
20
    }
21
22
    /**
23
     * Get a PHP style array from the current collection.
24
     *
25
     * @return array
26
     */
27
    public function toArray()
28
    {
29
        return $this->items;
30
    }
31
32
    /**
33
     * Whether the collection has the specified key, and/or value associated
34
     * with the specified key.
35
     *
36
     * @param string $key
37
     * @param mixed  $value
38
     *
39
     * @return bool
40
     */
41
    public function has($key, $value = null)
42
    {
43
        $key_exists = self::keyExists($key, $this->items);
44
45
        return null !== $value
46
            ? $value === $this->get($key)
47
            : $key_exists;
48
    }
49
50
    /**
51
     * Get the value associated with the specified key.
52
     *
53
     * @param string $key
54
     *
55
     * @throws \Enzyme\Collection\CollectionException If the key does not exist.
56
     *
57
     * @return mixed
58
     */
59
    public function get($key)
60
    {
61
        if (false === self::keyExists($key, $this->items)) {
62
            throw new CollectionException(
63
                "An element with the key [${key}] does not exist."
64
            );
65
        }
66
67
        return $this->items[$key];
68
    }
69
70
    /**
71
     * Get the value associated with the specified key or return a default value
72
     * instead if it does not exist.
73
     *
74
     * @param string $key
75
     * @param mixed  $default
76
     *
77
     * @return mixed
78
     */
79
    public function getOrDefault($key, $default = null)
80
    {
81
        try {
82
            return $this->get($key);
83
        } catch (CollectionException $e) {
84
            return $default;
85
        }
86
    }
87
88
    /**
89
     * Execute the given callback function for each element in this collection.
90
     *
91
     * @param Closure $fn
92
     */
93
    public function each(Closure $fn)
94
    {
95
        foreach ($this->items as $key => $value) {
96
            if (false === $fn($value, $key)) {
97
                break;
98
            }
99
        }
100
    }
101
102
    /**
103
     * Execute the given callback function for each element in this collection
104
     * and save the results to a new collection.
105
     *
106
     * @param Closure $fn
107
     *
108
     * @return \Enzyme\Collection\Collection
109
     */
110 View Code Duplication
    public function map(Closure $fn)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
111
    {
112
        $results = [];
113
        foreach ($this->items as $key => $value) {
114
            $results[] = $fn($value, $key);
115
        }
116
117
        return new static($results);
118
    }
119
120
    /**
121
     * Execute the given callback function for each element in this collection
122
     * and save the results to a new collection with the specified key. The
123
     * callback function should return a 1 element associative array, eg:
124
     * ['key' => 'value'] to be mapped.
125
     *
126
     * @param Closure $fn
127
     *
128
     * @return \Enzyme\Collection\Collection
129
     */
130
    public function mapWithKey(Closure $fn)
131
    {
132
        $results = [];
133
        foreach ($this->items as $key => $value) {
134
            $result = $fn($value, $key);
135
            $keys = array_keys($result);
136
137
            if (count($keys) < 1) {
138
                throw new CollectionException(
139
                    'Map with key expects a 1 element associative array.'
140
                );
141
            }
142
143
            $results[$keys[0]] = $result[$keys[0]];
144
        }
145
146
        return new static($results);
147
    }
148
149
    /**
150
     * Pluck out all values in this collection which have the specified key.
151
     *
152
     * @param string $pluck_key
153
     * @param bool   $deep      Whether to traverse into sub-arrays.
154
     *
155
     * @return \Enzyme\Collection\Collection
156
     */
157
    public function pluck($pluck_key, $deep = true)
158
    {
159
        return self::pluckKey($this->items, $pluck_key, $deep);
160
    }
161
162
    /**
163
     * Get the number of elements in this collection.
164
     *
165
     * @return int
166
     */
167
    public function count()
168
    {
169
        return count($this->items);
170
    }
171
172
    /**
173
     * Whether this collection is empty.
174
     *
175
     * @return bool
176
     */
177
    public function isEmpty()
178
    {
179
        return $this->count() < 1;
180
    }
181
182
    /**
183
     * Get the value of the first element in this collection.
184
     *
185
     * @throws \Enzyme\Collection\CollectionException If the collection is empty.
186
     *
187
     * @return mixed
188
     */
189
    public function first()
190
    {
191
        if (true === $this->isEmpty()) {
192
            throw new CollectionException(
193
                'Cannot get first item as the collection is empty.'
194
            );
195
        }
196
197
        return reset($this->items);
198
    }
199
200
    /**
201
     * Get the value of the first element in this collection or return the
202
     * default value specified if the collection is empty.
203
     *
204
     * @param mixed $default
205
     *
206
     * @return mixed
207
     */
208
    public function firstOrDefault($default = null)
209
    {
210
        try {
211
            return $this->first();
212
        } catch (CollectionException $e) {
213
            return $default;
214
        }
215
    }
216
217
    /**
218
     * Get the value of the last element in this collection.
219
     *
220
     * @throws \Enzyme\Collection\CollectionException If the collection is empty.
221
     *
222
     * @return mixed
223
     */
224
    public function last()
225
    {
226
        if (true === $this->isEmpty()) {
227
            throw new CollectionException(
228
                'Cannot get last element as collection is empty.'
229
            );
230
        }
231
232
        end($this->items);
233
        $key = key($this->items);
234
        reset($this->items);
235
236
        return $this->items[$key];
237
    }
238
239
    /**
240
     * Get the value of the last element in this collection or return the
241
     * default value specified if the collection is empty.
242
     *
243
     * @param mixed $default
244
     *
245
     * @return mixed
246
     */
247
    public function lastOrDefault($default = null)
248
    {
249
        try {
250
            return $this->first();
251
        } catch (CollectionException $e) {
252
            return $default;
253
        }
254
    }
255
256
    /**
257
     * Get a new collection of only the elements in the current collection
258
     * that have the specified keys.
259
     *
260
     * @param array $keys
261
     *
262
     * @return \Enzyme\Collection\Collection
263
     */
264
    public function only(array $keys)
265
    {
266
        return $this->filter(function ($value, $key) use ($keys) {
267
            return true === self::keyExists($key, array_flip($keys));
268
        });
269
    }
270
271
    /**
272
     * Get a new collection of all the elements in the current collection
273
     * except those that have the specified keys.
274
     *
275
     * @param array $keys
276
     *
277
     * @return \Enzyme\Collection\Collection
278
     */
279
    public function except(array $keys)
280
    {
281
        return $this->filter(function ($value, $key) use ($keys) {
282
            return false === self::keyExists($key, array_flip($keys));
283
        });
284
    }
285
286
    /**
287
     * Return a new collection with the current collection's elements plus the
288
     * given value pushed onto the end of the array.
289
     *
290
     * @param mixed $value
291
     *
292
     * @return \Enzyme\Collection\Collection
293
     */
294
    public function push($value)
295
    {
296
        $items = $this->items;
297
        $items[] = $value;
298
299
        return new static($items);
300
    }
301
302
    /**
303
     * Return a new collection with the current collection's elements plus the
304
     * given key and value pushed onto the end of the array.
305
     *
306
     * @param string $key
307
     * @param mixed  $value
308
     *
309
     * @return \Enzyme\Collection\Collection
310
     */
311
    public function pushWithKey($key, $value)
312
    {
313
        $items = $this->items;
314
        $items[$key] = $value;
315
316
        return new static($items);
317
    }
318
319
    /**
320
     * Return a new collection with the current collection's elements plus the
321
     * given array pushed onto the end of the array.
322
     *
323
     * @param array $data
324
     *
325
     * @return \Enzyme\Collection\Collection
326
     */
327
    public function pushArray(array $data)
328
    {
329
        $items = $this->items;
330
        foreach ($data as $key => $value) {
331
            if (true === is_int($key)) {
332
                $items[] = $value;
333
            } else {
334
                $items[$key] = $value;
335
            }
336
        }
337
338
        return new static($items);
339
    }
340
341
    /**
342
     * Return a new collection with a subset of all the current collection's
343
     * elements that pass the given callback functions truth test.
344
     *
345
     * @param Closure $fn
346
     *
347
     * @return \Enzyme\Collection\Collection
348
     */
349 View Code Duplication
    public function filter(Closure $fn)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
350
    {
351
        $results = [];
352
        foreach ($this->items as $key => $value) {
353
            if (true === $fn($value, $key)) {
354
                $results[$key] = $value;
355
            }
356
        }
357
358
        // Pushing this new array will normalize numeric keys if they exist.
359
        // After filtering, they may not start at zero and sequentially
360
        // go upwards, which is generally not expected.
361
        return (new static())->pushArray($results);
362
    }
363
364
    /**
365
     * Sort the collection using the provided callback function. Same expected
366
     * parameters and the PHP usort function.
367
     *
368
     * @param Closure $fn
369
     *
370
     * @return \Enzyme\Collection\Collection
371
     */
372
    public function sort(Closure $fn)
373
    {
374
        $sorted = $this->items;
375
        $result = usort($sorted, $fn);
376
377
        if (false === $result) {
378
            throw new CollectionException(
379
                'The collection could be not sorted.'
380
            );
381
        }
382
383
        return new static($sorted);
384
    }
385
386
    /**
387
     * Whether this collection has the specified number of elements within the
388
     * given range or equal too or above the minimum value specified.
389
     *
390
     * @param int $min
391
     * @param int $max Default is null.
392
     *
393
     * @return bool
394
     */
395
    public function hasCount($min, $max = null)
396
    {
397
        if (null === $max) {
398
            return $this->count() >= $min;
399
        }
400
401
        return $this->count() >= $min
402
            && $this->count() <= $max;
403
    }
404
405
    /**
406
     * Get a list of the keys used by this collection.
407
     *
408
     * @return array
409
     */
410
    public function keys()
411
    {
412
        return array_keys($this->items);
413
    }
414
415
    /**
416
     * Checks whether the specified key exists in the given collection.
417
     *
418
     * @param string $key
419
     * @param array  $collection
420
     *
421
     * @return bool
422
     */
423
    protected static function keyExists($key, array $collection)
424
    {
425
        return true === isset($collection[$key]);
426
    }
427
428
    /**
429
     * Pluck all the values that have the specified key from the given
430
     * collection.
431
     *
432
     * @param array  $collection
433
     * @param string $pluck_key
434
     * @param bool   $deep       Whether to traverse into sub-arrays.
435
     *
436
     * @return \Enzyme\Collection\Collection
437
     */
438
    protected static function pluckKey(array $collection, $pluck_key, $deep)
439
    {
440
        $results = [];
441
        foreach ($collection as $key => $value) {
442
            if (true === $deep && true === is_array($value)) {
443
                $deeper_results = self::pluckKey(
444
                    $value,
445
                    $pluck_key,
446
                    $deep
447
                )->toArray();
448
449
                foreach ($deeper_results as $deep_value) {
450
                    $results[] = $deep_value;
451
                }
452
453
                continue;
454
            }
455
456
            if ($key === $pluck_key) {
457
                $results[] = $value;
458
            }
459
        }
460
461
        return new static($results);
462
    }
463
}
464