Passed
Push — features/47-laravelmethods ( 9881c8...c6c948 )
by Luke
04:57 queued 02:25
created

Sequence::offsetSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Nozavroni/Collections
4
 * Just another collections library for PHP5.6+.
5
 * @version   {version}
6
 * @copyright Copyright (c) 2017 Luke Visinoni <[email protected]>
7
 * @author    Luke Visinoni <[email protected]>
8
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
9
 */
10
namespace Noz\Collection;
11
12
use ArrayAccess;
13
use BadMethodCallException;
14
15
use Countable;
16
use Traversable;
17
use SplFixedArray;
18
19
use Illuminate\Support\Str;
20
21
use Noz\Contracts\Structure\Sequenceable;
22
use Noz\Contracts\Immutable;
23
use Noz\Contracts\Arrayable;
24
use Noz\Contracts\Invokable;
25
26
use Noz\Traits\IsImmutable;
27
use Noz\Traits\IsContainer;
28
29
use function Noz\to_array;
30
use function Noz\is_traversable;
31
32
class Sequence implements
33
    ArrayAccess,
34
    Sequenceable,
35
    Immutable,
36
    Countable,
37
    Arrayable,
38
    Invokable
39
{
40
    use IsImmutable, IsContainer;
41
42
    /**
43
     * Delimiter used to fetch slices.
44
     */
45
    const SLICE_DELIM = ':';
46
47
    /**
48
     * Fixed-size data storage array.
49
     *
50
     * @var SplFixedArray
51
     */
52
    private $data;
53
54
    /**
55
     * Sequence constructor.
56
     *
57
     * @param array|Traversable $data The data to sequence
58
     */
59
    public function __construct($data)
60
    {
61
        $this->setData($data);
62
    }
63
64
    private function setData($data)
65
    {
66
        if (!is_traversable($data)) {
67
            // @todo Maybe create an ImmutableException for this?
68
            throw new BadMethodCallException(sprintf(
69
                'Cannot %s, %s is immutable.',
70
                __METHOD__,
71
                __CLASS__
72
            ));
73
        }
74
        $data = array_values(to_array($data));
75
        $this->data = SplFixedArray::fromArray($data);
76
    }
77
78
    protected function getData()
79
    {
80
        return $this->data->toArray();
81
    }
82
83
    /**
84
     * Count elements of an object
85
     * @link  http://php.net/manual/en/countable.count.php
86
     * @return int The custom count as an integer.
87
     * </p>
88
     * <p>
89
     * The return value is cast to an integer.
90
     * @since 5.1.0
91
     */
92
    public function count()
93
    {
94
        return $this->data->count();
95
    }
96
97
    public function toArray()
98
    {
99
        return $this->getData();
100
    }
101
102
    /**
103
     * Invoke sequence.
104
     * A sequence is invokable as if it were a function. This allows some pretty useful functionality such as negative
105
     * indexing, sub-sequence selection, etc.
106
     *
107
     * @internal param int $offset The offset to return
108
     *
109
     * @return mixed
110
     *
111
     * @todo Put all the slice logic into a helper function or several
112
     */
113
    public function __invoke()
114
    {
115
        $args = func_get_args();
116
        if (count($args)) {
117
            $count = $this->count();
118
            $offset = array_pop($args);
119
            if (Str::contains($offset, static::SLICE_DELIM)) {
120
                // return slice
121
                list($start, $end) = explode(static::SLICE_DELIM, $offset, 2);
122
                if ($start == '') {
123
                    $start = 0;
124
                }
125
                if ($end == '') {
126
                    $end = $count - 1;
127
                }
128
                if (is_numeric($start) && is_numeric($end)) {
129
                    if ($start < 0) {
130
                        $start = $count - abs($start);
131
                    }
132
                    if ($end < 0) {
133
                        $end = $count - abs($end);
134
                    }
135
                    $length = $end - $start + 1;
136
                    return new static(array_slice($this->getData(), $start, $length));
137
                }
138
            }
139
            if (is_numeric($offset)) {
140
                if ($offset < 0) {
141
                    $offset = $count - abs($offset);
142
                }
143
                return $this[$offset];
144
            }
145
        }
146
        return $this->toArray();
147
    }
148
149
    public function offsetGet($offset)
150
    {
151
        return $this->data->offsetGet($offset);
152
    }
153
154
    public function offsetSet($offset, $value)
155
    {
156
        // TODO: Implement offsetSet() method.
157
    }
158
159
    public function offsetUnset($offset)
160
    {
161
        // TODO: Implement offsetUnset() method.
162
    }
163
164
    public function offsetExists($offset)
165
    {
166
        return $this->data->offsetExists($offset);
167
    }
168
169
    /**
170
     * Prepend item to collection.
171
     * Prepend an item to this collection (in place).
172
     * @param mixed $item Item to prepend to collection
173
     * @return Sequence
174
     */
175
     public function prepend($item)
176
     {
177
         $arr = $this->getData();
178
         array_unshift($arr, $item);
179
         return new static($arr);
180
     }
181
182
    /**
183
     * Append item to collection.
184
     * Append an item to this collection (in place).
185
     * @param mixed $item Item to append to collection
186
     * @return Sequence
187
     */
188
    public function append($item)
189
    {
190
        $arr = $this->getData();
191
        array_push($arr, $item);
192
        return new static($arr);
193
    }
194
195
    public function fold(callable $funk, $initial = null)
196
    {
197
        return array_reduce($this->getData(), $funk, $initial);
198
    }
199
200
    /**
201
     * Is collection empty?
202
     * You may optionally pass in a callback which will determine if each of the items within the collection are empty.
203
     * If all items in the collection are empty according to this callback, this method will return true.
204
     * @param callable $callback The callback
0 ignored issues
show
Documentation introduced by
Should the type for parameter $callback not be null|callable? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
205
     * @return bool
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
206
     */
207
    public function isEmpty(callable $callback = null)
208
    {
209
210
    }
211
212
    /**
213
     * Pipe collection through callback.
214
     * Passes entire collection to provided callback and returns the result.
215
     * @param callable $callback
216
     * @return mixed
217
     */
218
    public function pipe(callable $callback)
219
    {
220
        // TODO: Implement pipe() method.
221
    }
222
223
    /**
224
     * Does every item return true?
225
     * If callback is provided, this method will return true if all items in collection cause callback to return true.
226
     * Otherwise, it will return true if all items in the collection have a truthy value.
227
     * @param callable|null $funk The callback
228
     * @return bool
229
     */
230
    public function every(callable $funk = null)
231
    {
232
        return $this->fold(function($carry, $val, $key, $iter) use ($funk) {
233
            if (!$carry) {
234
                return false;
235
            }
236
            if (!is_null($funk)) {
237
                return $funk($val, $key, $iter);
238
            }
239
            return (bool) $val;
240
        }, true);
241
    }
242
243
    /**
244
     * Does every item return false?
245
     * This method is the exact opposite of "all".
246
     * @param callable|null $funk The callback
247
     * @return bool
248
     */
249
    public function none(callable $funk = null)
250
    {
251
        return $this->fold(function($carry, $val, $key, $iter) use ($funk) {
252
            if ($carry) {
253
                return false;
254
            }
255
            if (!is_null($funk)) {
256
                return !$funk($val, $key, $iter);
257
            }
258
            return !((bool) $val);
259
        }, false);
260
    }
261
262
    public function first(callable $funk = null, $default = null)
263
    {
264
265
    }
266
267
    public function last(callable $funk = null, $default = null)
268
    {
269
        // TODO: Implement last() method.
270
    }
271
272
    /**
273
     * Return new sequence with the first item "bumped" off.
274
     * @return Sequenceable
0 ignored issues
show
Documentation introduced by
Should the return type not be Sequenceable|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
275
     */
276
    public function bump()
277
    {
278
        // TODO: Implement bump() method.
279
    }
280
281
    /**
282
     * Return new sequence with the last item "dropped" off.
283
     * @return Sequenceable
0 ignored issues
show
Documentation introduced by
Should the return type not be Sequenceable|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
284
     */
285
    public function drop()
286
    {
287
        // TODO: Implement drop() method.
288
    }
289
290
    public function getOffset($offset)
0 ignored issues
show
Unused Code introduced by
The parameter $offset 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...
291
    {
292
        // TODO: Implement getOffset() method.
293
    }
294
295
    public function hasOffset($offset)
0 ignored issues
show
Unused Code introduced by
The parameter $offset 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...
296
    {
297
        // TODO: Implement hasOffset() method.
298
    }
299
300
    public function setOffset($offset)
0 ignored issues
show
Unused Code introduced by
The parameter $offset 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...
301
    {
302
        // TODO: Implement setOffset() method.
303
    }
304
305
    public function unsetOffset($offset)
0 ignored issues
show
Unused Code introduced by
The parameter $offset 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...
306
    {
307
        // TODO: Implement unsetOffset() method.
308
    }
309
310
    /**
311
     * Get collection as a sequence.
312
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
313
     */
314
    public function toSeq()
315
    {
316
        // TODO: Implement toSeq() method.
317
    }
318
319
    /**
320
     * Get collection as a dictionary.
321
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
322
     */
323
    public function toDict()
324
    {
325
        // TODO: Implement toDict() method.
326
    }
327
328
    /**
329
     * Get collection as a set.
330
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
331
     */
332
    public function toSet()
333
    {
334
        // TODO: Implement toSet() method.
335
    }
336
337
    /**
338
     * Get collection as a map.
339
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
340
     */
341
    public function toMap()
342
    {
343
        // TODO: Implement toMap() method.
344
    }
345
346
    /**
347
     * Get collection as a list.
348
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
349
     */
350
    public function toList()
351
    {
352
        // TODO: Implement toList() method.
353
    }
354
}