BaseCollection::count()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Platine Collection
5
 *
6
 * Platine Collection provides a flexible and simple PHP collection implementation.
7
 *
8
 * This content is released under the MIT License (MIT)
9
 *
10
 * Copyright (c) 2020 Platine Collection
11
 *
12
 * Permission is hereby granted, free of charge, to any person obtaining a copy
13
 * of this software and associated documentation files (the "Software"), to deal
14
 * in the Software without restriction, including without limitation the rights
15
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
 * copies of the Software, and to permit persons to whom the Software is
17
 * furnished to do so, subject to the following conditions:
18
 *
19
 * The above copyright notice and this permission notice shall be included in all
20
 * copies or substantial portions of the Software.
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
 * SOFTWARE.
29
 */
30
31
/**
32
 *  @file BaseCollection.php
33
 *
34
 *  The BaseCollection class
35
 *
36
 *  @package    Platine\Collection
37
 *  @author Platine Developers Team
38
 *  @copyright  Copyright (c) 2020
39
 *  @license    http://opensource.org/licenses/MIT  MIT License
40
 *  @link   https://www.platine-php.com
41
 *  @version 1.0.0
42
 *  @filesource
43
 */
44
45
declare(strict_types=1);
46
47
namespace Platine\Collection;
48
49
use Countable;
50
use JsonSerializable;
51
use OutOfRangeException;
52
use Platine\Collection\Exception\InvalidOperationException;
53
54
/**
55
 * @class BaseCollection
56
 * @package Platine\Collection
57
 * @template T
58
 */
59
abstract class BaseCollection implements Countable, JsonSerializable
60
{
61
    /**
62
     * The data container instance
63
     * @var DataContainer<T>
64
     */
65
    protected DataContainer $data;
66
67
    /**
68
     * Create new instance
69
     * @param array<mixed, T> $initials
70
     */
71
    public function __construct(array $initials = [])
72
    {
73
        $this->data = new DataContainer($initials);
74
    }
75
76
    /**
77
     * Clear the collection data
78
     * @return void
79
     */
80
    public function clear(): void
81
    {
82
        $this->data = new DataContainer([]);
83
    }
84
85
    /**
86
     * Check whether the collection has the given element
87
     * @param T $needle
88
     * @return bool
89
     */
90
    public function contains(mixed $needle): bool
91
    {
92
        return in_array($needle, $this->all());
93
    }
94
95
    /**
96
     *
97
     * @param mixed $offset
98
     * @return bool
99
     */
100
    public function exists(mixed $offset): bool
101
    {
102
        return $this->data->offsetExists($offset);
103
    }
104
105
    /**
106
     * Return the first element of collection
107
     * @return T
108
     */
109
    public function first(): mixed
110
    {
111
        if ($this->isEmpty()) {
112
            throw new OutOfRangeException('The collection is empty');
113
        }
114
        $values = $this->all();
115
116
        return $values[0];
117
    }
118
119
    /**
120
     * Return the last element of collection
121
     * @return T
122
     */
123
    public function last(): mixed
124
    {
125
        if ($this->isEmpty()) {
126
            throw new OutOfRangeException('The collection is empty');
127
        }
128
        $values = $this->all();
129
130
        return $values[$this->count() - 1];
131
    }
132
133
    /**
134
     *
135
     * @return bool
136
     */
137
    public function isEmpty(): bool
138
    {
139
        return $this->count() === 0;
140
    }
141
142
    /**
143
     * Return the sum of the collection element
144
     * @param callable $callback
145
     * @return float
146
     */
147
    public function sum(callable $callback): float
148
    {
149
        $sum = 0;
150
        foreach ($this->data as $value) {
151
            $val = call_user_func($callback, $value);
152
            if (!is_numeric($val)) {
153
                throw new InvalidOperationException(
154
                    'You cannot sum non-numeric values'
155
                );
156
            }
157
158
            $sum += $val;
159
        }
160
161
        return $sum;
162
    }
163
164
    /**
165
     * Return the array representation of the collection
166
     * @return array<mixed, T>
167
     */
168
    public function all(): array
169
    {
170
        return $this->data->getData();
171
    }
172
173
    /**
174
     * {@inheritedoc}
175
     */
176
    public function count(): int
177
    {
178
        return count($this->all());
179
    }
180
181
    /**
182
     * {@inheritedoc}
183
     * @return array<mixed, T>
184
     */
185
    public function jsonSerialize(): array
186
    {
187
        return $this->all();
188
    }
189
190
    /**
191
     * Return the different with the given collection
192
     * @param BaseCollection<T> $collection
193
     * @return $this
194
     */
195
    abstract public function diff(BaseCollection $collection): self;
196
197
    /**
198
     * Whether two collections are equal
199
     * @param BaseCollection<T> $collection
200
     * @return bool
201
     */
202
    abstract public function equals(BaseCollection $collection): bool;
203
204
    /**
205
     * Returns a portion of the collection.
206
     * @param int $offset
207
     * @param int|null $length
208
     * @return null|$this
209
     */
210
    abstract public function slice(int $offset, ?int $length = null): ?self;
211
212
    /**
213
     * Fill the collection
214
     * @param array<mixed, T> $data
215
     * @return void
216
     */
217
    abstract public function fill(array $data): void;
218
219
    /**
220
     *
221
     * @return void
222
     */
223
    protected function repopulate(): void
224
    {
225
        $oldData = array_values($this->all());
226
        $this->data->setData($oldData);
227
    }
228
}
229