Passed
Pull Request — master (#64)
by
unknown
03:08
created

itertools.php ➔ accumulate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
crap 6
1
<?php
2
/**
3
 * @copyright Zicht Online <http://zicht.nl>
4
 */
5
6
namespace Zicht\Itertools;
7
8
use Zicht\Itertools\lib\AccumulateIterator;
9
use Zicht\Itertools\lib\ChainIterator;
10
use Zicht\Itertools\lib\CountIterator;
11
use Zicht\Itertools\lib\CycleIterator;
12
use Zicht\Itertools\lib\FilterIterator;
13
use Zicht\Itertools\lib\GroupbyIterator;
14
use Zicht\Itertools\lib\Interfaces\AccumulateInterface;
15
use Zicht\Itertools\lib\Interfaces\AllInterface;
16
use Zicht\Itertools\lib\Interfaces\ChainInterface;
17
use Zicht\Itertools\lib\Interfaces\CollapseInterface;
18
use Zicht\Itertools\lib\Interfaces\CycleInterface;
19
use Zicht\Itertools\lib\Interfaces\FilterInterface;
20
use Zicht\Itertools\lib\Interfaces\FiniteIterableInterface;
21
use Zicht\Itertools\lib\Interfaces\FirstInterface;
22
use Zicht\Itertools\lib\Interfaces\GroupByInterface;
23
use Zicht\Itertools\lib\Interfaces\LastInterface;
24
use Zicht\Itertools\lib\Interfaces\MapByInterface;
25
use Zicht\Itertools\lib\Interfaces\ReduceInterface;
26
use Zicht\Itertools\lib\Interfaces\ReversedInterface;
27
use Zicht\Itertools\lib\Interfaces\SliceInterface;
28
use Zicht\Itertools\lib\Interfaces\SortedInterface;
29
use Zicht\Itertools\lib\Interfaces\UniqueInterface;
30
use Zicht\Itertools\lib\Interfaces\ZipInterface;
31
use Zicht\Itertools\lib\IterableIterator;
32
use Zicht\Itertools\lib\MapByIterator;
33
use Zicht\Itertools\lib\MapIterator;
34
use Zicht\Itertools\lib\RepeatIterator;
35
use Zicht\Itertools\lib\ReversedIterator;
36
use Zicht\Itertools\lib\SliceIterator;
37
use Zicht\Itertools\lib\SortedIterator;
38
use Zicht\Itertools\lib\UniqueIterator;
39
use Zicht\Itertools\lib\ZipIterator;
40
use Zicht\Itertools\reductions;
41
use Zicht\Itertools\util\Conversions;
42
43
/**
44
 * Transforms anything into an \Iterator or throws an \InvalidArgumentException
45
 *
46
 * @param array|string|\Iterator $iterable
47
 * @return \Iterator
48
 * @deprecated Use \Zicht\Itertools\util\Conversions::mixedToIterator, will be removed in version 3.0
49
 */
50
function mixedToIterator($iterable) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
51
{
52
    return Conversions::mixedToIterator($iterable);
53
}
54
55
/**
56
 * Try to transforms something into a \Closure
57
 *
58
 * @param null|\Closure $closure
59
 * @return \Closure
60
 * @deprecated Use \Zicht\Itertools\util\Conversions::mixedToClosure, will be removed in version 3.0
61
 */
62
function mixedToClosure($closure) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
63
{
64
    return Conversions::mixedToClosure($closure);
65
}
66
67
/**
68
 * Try to transforms something into a \Closure that gets a value from $strategy
69
 *
70
 * @param null|string|\Closure $strategy
71
 * @return \Closure
72
 * @deprecated Use \Zicht\Itertools\util\Conversions::mixedToValueGetter, will be removed in version 3.0
73
 */
74
function mixedToValueGetter($strategy) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
75
{
76
    return Conversions::mixedToValueGetter($strategy);
77
}
78
79
/**
80
 * Try to transform something into a \Closure
81
 *
82
 * @param string|\Closure $closure
83
 * @return \Closure
84
 * @deprecated Will be removed in version 3.0, no replacement will be needed
85
 */
86
function mixedToOperationClosure($closure) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
87
{
88
    if (is_string($closure)) {
89
        $closure = reductions\get_reduction($closure, $closure);
0 ignored issues
show
Deprecated Code introduced by
The function Zicht\Itertools\reductions\get_reduction() has been deprecated with message: please use the reduction functions directly, will be removed in version 3.0

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
90
    }
91
92
    if (!($closure instanceof \Closure)) {
93
        throw new \InvalidArgumentException('Argument $closure must be a \Closure or string (i.e. "add", "join", etc)');
94
    }
95
96
    return $closure;
97
}
98
99
/**
100
 * Make an iterator that returns accumulated sums
101
 *
102
 * If the optional $closure argument is supplied, it should be a string:
103
 * add, sub, mul, min, or max.  Or it can be a \Closure taking two
104
 * arguments that will be used to instead of addition.
105
 *
106
 * > accumulate([1,2,3,4,5])
107
 * 1 3 6 10 15
108
 *
109
 * > accumulate(['One', 'Two', 'Three'], function ($a, $b) { return $a . $b; })
110
 * 'One' 'OneTwo' 'OneTwoThree'
111
 *
112
 * @param array|string|\Iterator $iterable
113
 * @param string|\Closure $closure
114
 * @return AccumulateIterator
115
 * @deprecated Use iterable($iterable)->accumulate($closure), will be removed in version 3.0
116
 */
117
function accumulate($iterable, $closure = 'add')
118
{
119
    if (!($iterable instanceof AccumulateInterface)) {
120
        $iterable = iterable($iterable);
121
    }
122
123
    return $iterable->accumulate($closure);
124
}
125
126
/**
127
 * Reduce an iterator to a single value
128
 *
129
 * > reduce([1,2,3])
130
 * 6
131
 *
132
 * > reduce([1,2,3], 'max')
133
 * 3
134
 *
135
 * > reduce([1,2,3], 'sub', 10)
136
 * 4
137
 *
138
 * > reduce([], 'min', 1)
139
 * 1
140
 *
141
 * @param array|string|\Iterator $iterable
142
 * @param string|\Closure $closure
143
 * @param mixed $initializer
144
 * @return mixed
145
 * @deprecated Use iterable($iterable)->reduce($closure, $initializer), will be removed in version 3.0
146
 */
147
function reduce($iterable, $closure = 'add', $initializer = null)
148
{
149
    if (!($iterable instanceof ReduceInterface)) {
150
        $iterable = iterable($iterable);
151
    }
152
153
    return $iterable->reduce($closure, $initializer);
154
}
155
156
/**
157
 * Collapse a two dimentional iterator into a one dimentional iterator
158
 *
159
 * > collapse([1, 2], [3, 4])
160
 * 1, 2, 3, 4
161
 *
162
 * @param array|string|\Iterator $iterable
163
 * @return lib\CollapseIterator
164
 * @deprecated Use iterable($iterable)->collapse(), will be removed in version 3.0
165
 */
166
function collapse($iterable)
167
{
168
    if (!($iterable instanceof CollapseInterface)) {
169
        $iterable = iterable($iterable);
170
    }
171
172
    return $iterable->collapse();
173
}
174
175
/**
176
 * Make an iterator that contains all consecutive elements from all provided iterables.
177
 *
178
 * The resulting iterator contains elements from the first iterable in the parameters
179
 * until it is exhausted, then proceeds to the next iterable in the parameters, until
180
 * all the iterables are exhausted.  Used for creating consecutive
181
 * sequences as a single sequence
182
 *
183
 * > chain([1, 2, 3], [4, 5, 6])
184
 * 1 2 3 4 5 6
185
 *
186
 * > chain('ABC', 'DEF')
187
 * A B C D E F
188
 *
189
 * @return ChainIterator
190
 * @deprecated Use iterable($iterable)->chain($iterable, ...), will be removed in version 3.0
191
 */
192
function chain()
193
{
194
    // note, once we stop supporting php 5.5, we can rewrite the code below
195
    // to the chain(...$iterables) structure.
196
    // http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
197
198
    $args = func_get_args();
199
    if (sizeof($args) > 0) {
200
        list($iterable) = array_slice($args, 0, 1);
201
        $iterables = array_slice($args, 1);
202
    } else {
203
        $iterable = null;
204
        $iterables = [];
205
    }
206
207
    if (!($iterable instanceof ChainInterface)) {
208
        $iterable = iterable($iterable);
209
    }
210
211
    return call_user_func_array([$iterable, 'chain'], $iterables);
212
}
213
214
/**
215
 * Make an iterator that returns evenly spaced values starting with
216
 * number $start
217
 *
218
 * > count(10)
219
 * 10 11 12 13 14 ...
220
 *
221
 * > count(2.5, 0.5)
222
 * 2.5 3.0 3.5 4.0 ...
223
 *
224
 * @param int|float $start
225
 * @param int|float $step
226
 * @return CountIterator
227
 * @deprecated Use new CountIterator($start, $step), will be removed in version 3.0
228
 */
229
function count($start = 0, $step = 1)
230
{
231
    if (!(is_int($start) || is_float($start))) {
232
        throw new \InvalidArgumentException('Argument $start must be an integer or float');
233
    }
234
235
    if (!(is_int($step) || is_float($step))) {
236
        throw new \InvalidArgumentException('Argument $step must be an integer or float');
237
    }
238
239
    return new CountIterator($start, $step);
240
}
241
242
/**
243
 * Make an iterator returning elements from the $iterable and saving a
244
 * copy of each.  When the iterable is exhausted, return elements from
245
 * the saved copy, repeating indefinitely
246
 *
247
 * > cycle('ABCD')
248
 * A B C D A B C D A B C D ...
249
 *
250
 * @param array|string|\Iterator $iterable
251
 * @return CycleIterator
252
 * @deprecated Use iterable($iterable)->cycle(), will be removed in version 3.0
253
 */
254
function cycle($iterable)
255
{
256
    if (!($iterable instanceof CycleInterface)) {
257
        $iterable = iterable($iterable);
258
    }
259
260
    return $iterable->cycle();
261
}
262
263
/**
264
 * Make an iterator returning values from $iterable and keys from
265
 * $strategy
266
 *
267
 * When $strategy is a string, the key is obtained through one of
268
 * the following:
269
 * 1. $value->{$strategy}, when $value is an object and
270
 *    $strategy is an existing property,
271
 * 2. call $value->{$strategy}(), when $value is an object and
272
 *    $strategy is an existing method,
273
 * 3. $value[$strategy], when $value is an array and $strategy
274
 *    is an existing key,
275
 * 4. otherwise the key will default to null.
276
 *
277
 * Alternatively $strategy can be a closure.  In this case the
278
 * $strategy closure is called with each value in $iterable and the
279
 * key will be its return value.
280
 *
281
 * > $list = [['id'=>1, 'title'=>'one'], ['id'=>2, 'title'=>'two']]
282
 * > mapBy('id', $list)
283
 * 1=>['id'=>1, 'title'=>'one'] 2=>['id'=>2, 'title'=>'two']
284
 *
285
 * @param null|string|\Closure $strategy
286
 * @param array|string|\Iterator $iterable
287
 * @return MapByIterator
288
 * @deprecated Use iterable($iterable)->mapBy($strategy), will be removed in version 3.0
289
 */
290
function map_by($strategy, $iterable)
291
{
292
    // In version 3.0 mapBy and map_by will be removed
293
    // as its functionality will be merged into map.
294
295
    if (!($iterable instanceof MapByInterface)) {
296
        $iterable = iterable($iterable);
297
    }
298
299
    return $iterable->mapBy($strategy);
300
}
301
302
/**
303
 * Make an iterator returning values from $iterable and keys from
304
 * $strategy
305
 *
306
 * @param null|string|\Closure $strategy
307
 * @param array|string|\Iterator $iterable
308
 * @return MapByIterator
309
 * @deprecated Please use map_by, will be removed in version 3.0
310
 * @deprecated Use iterable($iterable)->mapBy($strategy), will be removed in version 3.0
311
 */
312
function mapBy($strategy, $iterable) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
313
{
314
    if (!($iterable instanceof MapByInterface)) {
315
        $iterable = iterable($iterable);
316
    }
317
318
    return $iterable->mapBy($strategy);}
319
320
/**
321
 * Make an iterator returning values from $iterable and keys from
322
 * $strategy
323
 *
324
 * @param null|string|\Closure $strategy
325
 * @param array|string|\Iterator $iterable
326
 * @return MapByIterator
327
 * @deprecated Use iterable($iterable)->mapBy($strategy), will be removed in version 3.0
328
 */
329
function keyCallback($strategy, $iterable) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
330
{
331
    return map_by($strategy, $iterable);
332
}
333
334
/**
335
 * Make an iterator that applies $strategy to every entry in the iterables
336
 *
337
 * If one iterable is passed, $strategy is called for each entry in
338
 * the $iterable, where the first argument is the value and the
339
 * second argument is the key of the entry
340
 *
341
 * If more than one iterable is passed, $strategy is called with the
342
 * values and the keys from the iterables.  For example, the first
343
 * call to $strategy will be:
344
 * $strategy($value_iterable1, $value_iterable2, $key_iterable2, $key_iterable2)
345
 *
346
 * With multiple iterables, the iterator stops when the shortest
347
 * iterable is exhausted.
348
 *
349
 * > $minimal = function ($value) { return min(3, $value); };
350
 * > map($minimal, [1, 2, 3, 4]);
351
 * 3 3 3 4
352
 *
353
 * > $average = function ($value1, $value2) { return ($value1 + $value2) / 2; };
354
 * > map($average, [1, 2, 3], [4, 5, 6]);
355
 * 2.5 3.5 4.5
356
 *
357
 * @param null|string|\Closure $strategy
358
 * @param array|string|\Iterator $iterable Additional $iterable parameters may follow
359
 * @return MapIterator
360
 * @deprecated Use iterable($iterable)->map($strategy, [$iterable2, ...]), will be removed in version 3.0
361
 */
362 View Code Duplication
function map($strategy, $iterable)
0 ignored issues
show
Duplication introduced by
This function 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...
363
{
364
    // note, once we stop supporting php 5.5, we can rewrite the code below
365
    // to the map(...$iterables) structure.
366
    // http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
367
368
    if (func_num_args() > 2) {
369
        $iterables = array_slice(func_get_args(), 2);
370
    } else {
371
        $iterables = [];
372
    }
373
374
    if (!($iterable instanceof ChainInterface)) {
375
        $iterable = iterable($iterable);
376
    }
377
378
    return call_user_func_array([$iterable, 'map'], array_merge([$strategy], $iterables));
379
}
380
381
/**
382
 * Select values from the iterator by applying a function to each of the iterator values, i.e., mapping it to the
383
 * value with a strategy based on the input, similar to map_key
384
 *
385
 * @param null|string|\Closure $strategy
386
 * @param array|string|\Iterator $iterable
387
 * @param bool $flatten
388
 * @return array|MapIterator
389
 * @deprecated Use map(...)->values() instead (when flatten true), will be removed in version 3.0
390
 */
391
function select($strategy, $iterable, $flatten = true)
392
{
393
    if (!is_bool($flatten)) {
394
        throw new \InvalidArgumentException('Argument $FLATTEN must be a boolean');
395
    }
396
397
    $ret = new MapIterator(
398
        Conversions::mixedToValueGetter($strategy),
399
        Conversions::mixedToIterator($iterable)
400
    );
401
    if ($flatten) {
402
        return $ret->values();
403
    }
404
    return $ret;
405
}
406
407
/**
408
 * Make an iterator that returns $mixed over and over again.  Runs
409
 * indefinitely unless the $times argument is specified
410
 *
411
 * > repeat(2)
412
 * 2 2 2 2 2 ...
413
 *
414
 * > repeat(10, 3)
415
 * 10 10 10
416
 *
417
 * @param mixed $mixed
418
 * @param null|int $times
419
 * @return RepeatIterator
420
 * @deprecated Use new RepeatIterator(mixed, $times), will be removed in version 3.0
421
 */
422
function repeat($mixed, $times = null)
423
{
424
    if (!(is_null($times) || (is_int($times) && $times >= 0))) {
425
        throw new \InvalidArgumentException('Argument $times must be null or a positive integer');
426
    }
427
428
    return new RepeatIterator($mixed, $times);
429
}
430
431
/**
432
 * Make an iterator that returns consecutive groups from the
433
 * $iterable.  Generally, the $iterable needs to already be sorted on
434
 * the same key function
435
 *
436
 * When $strategy is a string, the key is obtained through one of
437
 * the following:
438
 * 1. $value->{$strategy}, when $value is an object and
439
 *    $strategy is an existing property,
440
 * 2. call $value->{$strategy}(), when $value is an object and
441
 *    $strategy is an existing method,
442
 * 3. $value[$strategy], when $value is an array and $strategy
443
 *    is an existing key,
444
 * 4. otherwise the key will default to null.
445
 *
446
 * Alternatively $strategy can be a closure.  In this case the
447
 * $strategy closure is called with each value in $iterable and the
448
 * key will be its return value.  $strategy is called with two
449
 * parameters: the value and the key of the iterable as the first and
450
 * second parameter, respectively.
451
 *
452
 * The operation of groupBy() is similar to the uniq filter in Unix.
453
 * It generates a break or new group every time the value of the key
454
 * function changes (which is why it is usually necessary to have
455
 * sorted the data using the same key function).  That behavior
456
 * differs from SQL's GROUP BY which aggregates common elements
457
 * regardless of their input order.
458
 *
459
 * > $list = [['type'=>'A', 'title'=>'one'], ['type'=>'A', 'title'=>'two'], ['type'=>'B', 'title'=>'three']]
460
 * > groupby('type', $list)
461
 * 'A'=>[['type'=>'A', 'title'=>'one'], ['type'=>'A', 'title'=>'two']] 'B'=>[['type'=>'B', 'title'=>'three']]
462
 *
463
 * @param null|string|\Closure $strategy
464
 * @param array|string|\Iterator $iterable
465
 * @param boolean $sort
466
 * @return GroupbyIterator
467
 * @deprecated Use iterable($iterable)->groupBy($strategy, $sort), will be removed in version 3.0
468
 */
469
function group_by($strategy, $iterable, $sort = true)
470
{
471
    if (!($iterable instanceof GroupByInterface)) {
472
        $iterable = iterable($iterable);
473
    }
474
475
    return $iterable->groupBy($strategy, $sort);
476
}
477
478
/**
479
 * Make an iterator that returns consecutive groups from the
480
 * $iterable.  Generally, the $iterable needs to already be sorted on
481
 * the same key function
482
 *
483
 * @param null|string|\Closure $strategy
484
 * @param array|string|\Iterator $iterable
485
 * @param boolean $sort
486
 * @return GroupbyIterator
487
 * @deprecated Use iterable($iterable)->groupBy($strategy, $sort), will be removed in version 3.0
488
 */
489
function groupBy($strategy, $iterable, $sort = true) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
490
{
491
    if (!($iterable instanceof GroupByInterface)) {
492
        $iterable = iterable($iterable);
493
    }
494
495
    return $iterable->groupBy($strategy, $sort);
496
}
497
498
/**
499
 * Make an iterator that returns the values from $iterable sorted by
500
 * $strategy
501
 *
502
 * When determining the order of two entries the $strategy is called
503
 * twice, once for each value, and the results are used to determine
504
 * the order.  $strategy is called with two parameters: the value and
505
 * the key of the iterable as the first and second parameter, respectively.
506
 *
507
 * When $reverse is true the order of the results are reversed.
508
 *
509
 * The sorted() function is guaranteed to be stable.  A sort is stable
510
 * if it guarantees not to change the relative order of elements that
511
 * compare equal.  this is helpful for sorting in multiple passes (for
512
 * example, sort by department, then by salary grade).  This also
513
 * holds up when $reverse is true.
514
 *
515
 * > $list = [['type'=>'B', 'title'=>'second'], ['type'=>'C', 'title'=>'third'], ['type'=>'A', 'title'=>'first']]
516
 * > sorted('type', $list)
517
 * ['type'=>'A', 'title'=>'first'] ['type'=>'B', 'title'=>'second']] ['type'=>'C', 'title'=>'third']
518
 *
519
 * @param null|string|\Closure $strategy
520
 * @param array|string|\Iterator $iterable
521
 * @param boolean $reverse
522
 * @return SortedIterator
523
 * @deprecated Use iterable($iterable)->sorted($strategy, $reverse), will be removed in version 3.0
524
 */
525
function sorted($strategy, $iterable, $reverse = false)
526
{
527
    if (!($iterable instanceof SortedInterface)) {
528
        $iterable = iterable($iterable);
529
    }
530
531
    return $iterable->sorted($strategy, $reverse);
532
}
533
534
/**
535
 * Make an iterator that returns values from $iterable where the
536
 * $strategy determines that the values are not empty
537
 *
538
 * An optional $strategy may be given, this must be either null,
539
 * a string, or a \Closure.
540
 *
541
 * Following the (optional) $strategy, one or more $iterable instances
542
 * must be given.  They must be either an array, a string, or an \Iterator.
543
 *
544
 * @return FilterIterator
545
 * @deprecated Use iterable($iterable)->filter($strategy), will be removed in version 3.0
546
 */
547 View Code Duplication
function filter()
0 ignored issues
show
Duplication introduced by
This function 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...
548
{
549
    // note, once we stop supporting php 5.5, we can rewrite the code below
550
    // to the filter(...$iterables) structure.
551
    // http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
552
553
    $args = func_get_args();
554
    switch (sizeof($args)) {
555
        case 1:
556
            $strategy = null;
557
            $iterable = $args[0];
558
            break;
559
560
        case 2:
561
            $strategy = $args[0];
562
            $iterable = $args[1];
563
            break;
564
565
        default:
566
            throw new \InvalidArgumentException('filter requires either one (iterable) or two (strategy, iterable) arguments');
567
    }
568
569
    if (!($iterable instanceof FilterInterface)) {
570
        $iterable = iterable($iterable);
571
    }
572
573
    return $iterable->filter($strategy);
574
}
575
576
/**
577
 * Make an iterator that returns values from $iterable where the
578
 * $strategy determines that the values are not empty
579
 *
580
 * An $strategy must be given, this must be either null, a string,
581
 * or a \Closure.
582
 *
583
 * Following the $strategy, an optional $closure may be given, this
584
 * closure is called to determine is the value (which results from
585
 * $strategy) is or is not filtered.  Note that without providing a
586
 * $closure, the function !empty(...) is used instead.
587
 *
588
 * Following the (optional) $closure, one or more $iterable instances
589
 * must be given.  They must be either an array, a string, or an \Iterator.
590
 *
591
 * @return FilterIterator
592
 * @deprecated Use iterable($iterable)->filter($strategy), will be removed in version 3.0
593
 */
594
function filterBy() // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
595
{
596
    // note, once we stop supporting php 5.5, we can rewrite the code below
597
    // to the filterBy(...$iterables) structure.
598
    // http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
599
600
    $args = func_get_args();
601
    switch (sizeof($args)) {
602 View Code Duplication
        case 2:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
603
            $strategy = Conversions::mixedToValueGetter($args[0]);
604
            $closure = function ($value, $key) use ($strategy) {
605
                $tempVarPhp54 = call_user_func($strategy, $value, $key);
606
                return !empty($tempVarPhp54);
607
            };
608
            $iterable = Conversions::mixedToIterator($args[1]);
609
            break;
610
611 View Code Duplication
        case 3:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
612
            $strategy = Conversions::mixedToValueGetter($args[0]);
613
            $userClosure = $args[1];
614
            $closure = function ($value, $key) use ($strategy, $userClosure) {
615
                return call_user_func($userClosure, call_user_func($strategy, $value, $key));
616
            };
617
            $iterable = Conversions::mixedToIterator($args[2]);
618
            break;
619
620
        default:
621
            throw new \InvalidArgumentException('filterBy requires either two (strategy, iterable) or three (strategy, closure, iterable) arguments');
622
    }
623
624
    return new FilterIterator($closure, $iterable);
625
}
626
627
/**
628
 * Returns an iterator where one or more iterables are zipped together
629
 *
630
 * This function returns a list of tuples, where the i-th tuple contains
631
 * the i-th element from each of the argument sequences or iterables.
632
 *
633
 * The returned list is truncated in length to the length of the
634
 * shortest argument sequence.
635
 *
636
 * > zip([1, 2, 3], ['a', 'b', 'c'])
637
 * [1, 'a'] [2, 'b'] [3, 'c']
638
 *
639
 * @param array|string|\Iterator $iterable Additional $iterable parameters may follow
640
 * @return ZipIterator
641
 * @deprecated Use iterable($iterable)->zip($iterable2, [$iterable3, ...]), will be removed in version 3.0
642
 */
643 View Code Duplication
function zip($iterable)
0 ignored issues
show
Duplication introduced by
This function 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...
644
{
645
    // note, once we stop supporting php 5.5, we can rewrite the code below
646
    // to the zip(...$iterables) structure.
647
    // http://php.net/manual/en/functions.arguments.php#functions.variable-arg-list
648
649
    if (func_num_args() > 1) {
650
        $iterables = array_slice(func_get_args(), 1);
651
    } else {
652
        $iterables = [];
653
    }
654
655
    if (!($iterable instanceof ZipInterface)) {
656
        $iterable = iterable($iterable);
657
    }
658
659
    return call_user_func_array([$iterable, 'zip'], $iterables);
660
}
661
662
/**
663
 * Returns an iterable with all the elements from $iterable reversed
664
 *
665
 * @param array|string|\Iterator $iterable
666
 * @return ReversedIterator
667
 * @deprecated Use iterable($iterable)->reversed(), will be removed in version 3.0
668
 */
669
function reversed($iterable)
670
{
671
    if (!($iterable instanceof ReversedInterface)) {
672
        $iterable = iterable($iterable);
673
    }
674
675
    return $iterable->reversed();
676
}
677
678
/**
679
 * Returns an iterator where the values from $strategy are unique
680
 *
681
 * An optional $strategy may be given to specify the value which is used
682
 * to determine whether the element is unique.  When no $strategy is
683
 * given, the identity function is used, i.e. the value of the element
684
 * itself is used to determine whether the element is unique.
685
 *
686
 * Following the optional $strategy, a $iterable must be given.  Otherwise,
687
 * an \InvalidArgumentException will be raised.
688
 *
689
 * > unique([1, 1, 2, 2, 3, 3])
690
 * 1 2 3
691
 *
692
 * > unique('id', [['id' => 1, 'value' => 'a'], ['id' => 1, 'value' => 'b']])
693
 * ['id' => 1, 'value' => 'a']  # one element in this list
694
 *
695
 * @return UniqueIterator
696
 * @deprecated Use iterable($iterable)->unique($strategy), will be removed in version 3.0
697
 */
698 View Code Duplication
function unique()
0 ignored issues
show
Duplication introduced by
This function 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...
699
{
700
    $args = func_get_args();
701
    switch (sizeof($args)) {
702
        case 1:
703
            $strategy = null;
704
            $iterable = $args[0];
705
            break;
706
707
        case 2:
708
            $strategy = $args[0];
709
            $iterable = $args[1];
710
            break;
711
712
        default:
713
            throw new \InvalidArgumentException('unique requires either one (iterable) or two (strategy, iterable) arguments');
714
    }
715
716
    if (!($iterable instanceof UniqueInterface)) {
717
        $iterable = iterable($iterable);
718
    }
719
720
    return $iterable->unique($strategy);
721
}
722
723
/**
724
 * Returns an iterator where the values from $strategy are unique
725
 *
726
 * @param null|string|\Closure $strategy
727
 * @param array|string|\Iterator $iterable
728
 * @return UniqueIterator
729
 * @deprecated Use iterable($iterable)->unique($strategy), will be removed in version 3.0
730
 */
731 View Code Duplication
function uniqueBy($strategy, $iterable) // phpcs:ignore Zicht.NamingConventions.Functions.GlobalNaming
0 ignored issues
show
Duplication introduced by
This function 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...
Unused Code introduced by
The parameter $iterable 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...
Unused Code introduced by
The parameter $strategy 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...
732
{
733
    $args = func_get_args();
734
    switch (sizeof($args)) {
735
        case 1:
736
            $strategy = null;
737
            $iterable = $args[0];
738
            break;
739
740
        case 2:
741
            $strategy = $args[0];
742
            $iterable = $args[1];
743
            break;
744
745
        default:
746
            throw new \InvalidArgumentException('unique requires either one (iterable) or two (strategy, iterable) arguments');
747
    }
748
749
    if (!($iterable instanceof UniqueInterface)) {
750
        $iterable = iterable($iterable);
751
    }
752
753
    return $iterable->unique($strategy);
754
}
755
756
/**
757
 * Returns true when one or more element of $iterable is not empty, otherwise returns false
758
 *
759
 * An optional $strategy may be given to specify the value which is used
760
 * to determine weather the element evaluates to true.  When no $strategy is
761
 * given, the identity function is used, i.e. the value of the element
762
 * itself is used to determine weather the element evaluates to true.
763
 *
764
 * Following the optional $strategy, an $iterable may be given.  Its type may
765
 * be either array, string, or \Iterator.  When no $iterable is given, false
766
 * is returned.
767
 *
768
 * > any([0, '', false])
769
 * false
770
 *
771
 * > any([1, null, 3])
772
 * true
773
 *
774
 * @return boolean
775
 * @deprecated Use iterable($iterable)->any($strategy), will be removed in version 3.0
776
 */
777 View Code Duplication
function any()
0 ignored issues
show
Duplication introduced by
This function 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...
778
{
779
    $args = func_get_args();
780
    switch (sizeof($args)) {
781
        case 1:
782
            $strategy = null;
783
            $iterable = $args[0];
784
            break;
785
786
        case 2:
787
            $strategy = $args[0];
788
            $iterable = $args[1];
789
            break;
790
791
        default:
792
            throw new \InvalidArgumentException('any requires either one (iterable) or two (strategy, iterable) arguments');
793
    }
794
795
    if (!($iterable instanceof AllInterface)) {
796
        $iterable = iterable($iterable);
797
    }
798
799
    return $iterable->any($strategy);
800
}
801
802
/**
803
 * Returns true when all elements of $iterable are not empty, otherwise returns false
804
 *
805
 * An optional $strategy may be given to specify the value which is used
806
 * to determine weather the element evaluates to true.  When no $strategy is
807
 * given, the identity function is used, i.e. the value of the element
808
 * itself is used to determine weather the element evaluates to true.
809
 *
810
 * Following the optional $strategy, an $iterable may be given.  Its type may
811
 * be either array, string, or \Iterator.  When no $iterable is given, true
812
 * is returned.
813
 *
814
 * > all([1, 'hello world', true])
815
 * true
816
 *
817
 * > all([1, null, 3])
818
 * false
819
 *
820
 * @return boolean
821
 * @deprecated Use iterable($iterable)->all($strategy), will be removed in version 3.0
822
 */
823 View Code Duplication
function all()
0 ignored issues
show
Duplication introduced by
This function 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...
824
{
825
    $args = func_get_args();
826
    switch (sizeof($args)) {
827
        case 1:
828
            $strategy = null;
829
            $iterable = $args[0];
830
            break;
831
832
        case 2:
833
            $strategy = $args[0];
834
            $iterable = $args[1];
835
            break;
836
837
        default:
838
            throw new \InvalidArgumentException('all requires either one (iterable) or two (strategy, iterable) arguments');
839
    }
840
841
    if (!($iterable instanceof AllInterface)) {
842
        $iterable = iterable($iterable);
843
    }
844
845
    return $iterable->all($strategy);
846
}
847
848
/**
849
 * Make an iterator that contains a slice of $iterable
850
 *
851
 * The parameters $start and $end determine the range that will be taken
852
 * from the $iterable.  These values may be negative, in which case they
853
 * will indicate elements in $iterable starting at the end.
854
 *
855
 * > slice(['a', 'b', 'c', 'd', 'e', 1]
856
 * 'b', 'c', 'd', 'e'
857
 *
858
 * > slice(['a', 'b', 'c', 'd', 'e', -1]
859
 * 'e'
860
 *
861
 * > slice(['a', 'b', 'c', 'd', 'e', 1, 2]
862
 * 'b'
863
 *
864
 * > slice(['a', 'b', 'c', 'd', 'e', 1, -1]
865
 * 'b', 'c', 'd'
866
 *
867
 * @param array|string|\Iterator $iterable
868
 * @param int $start
869
 * @param null|int $end
870
 * @return SliceIterator
871
 * @deprecated Use iterable($iterable)->slice($start, $end), will be removed in version 3.0
872
 */
873
function slice($iterable, $start, $end = null)
874
{
875
    if (!($iterable instanceof SliceInterface)) {
876
        $iterable = iterable($iterable);
877
    }
878
879
    return $iterable->slice($start, $end);
880
}
881
882
/**
883
 * Returns the first element of $iterable or returns $default when $iterable is empty
884
 *
885
 * > first([1, 2, 3])
886
 * 1
887
 *
888
 * > first([])
889
 * null
890
 *
891
 * @param array|string|\Iterator $iterable
892
 * @param mixed $default
893
 * @return mixed
894
 * @deprecated Use iterable($iterable)->first($default), will be removed in version 3.0
895
 */
896
function first($iterable, $default = null)
897
{
898
    if (!($iterable instanceof FirstInterface)) {
899
        $iterable = iterable($iterable);
900
    }
901
902
    return $iterable->first($default);
903
}
904
905
/**
906
 * Returns the key of the first element of $iterable or returns $default when $iterable is empty
907
 *
908
 * > first_key([1, 2, 3])
909
 * 0
910
 *
911
 * > first_key([])
912
 * null
913
 *
914
 * @param array|string|\Iterator $iterable
915
 * @param mixed $default
916
 * @return mixed
917
 * @deprecated Use iterable($iterable)->firstKey($default), will be removed in version 3.0
918
 */
919
function first_key($iterable, $default = null)
920
{
921
    if (!($iterable instanceof FirstInterface)) {
922
        $iterable = iterable($iterable);
923
    }
924
925
    return $iterable->firstKey($default);
926
}
927
928
/**
929
 * Returns the last element of $iterable or returns $default when $iterable is empty
930
 *
931
 * > last([1, 2, 3])
932
 * 3
933
 *
934
 * > last([])
935
 * null
936
 *
937
 * @param array|string|\Iterator $iterable
938
 * @param mixed $default
939
 * @return mixed
940
 * @deprecated Use iterable($iterable)->last($default), will be removed in version 3.0
941
 */
942
function last($iterable, $default = null)
943
{
944
    if (!($iterable instanceof LastInterface)) {
945
        $iterable = iterable($iterable);
946
    }
947
948
    return $iterable->last($default);
949
}
950
951
/**
952
 * Returns the key of the last element of $iterable or returns $default when $iterable is empty
953
 *
954
 * > last_key([1, 2, 3])
955
 * 2
956
 *
957
 * > last_key([])
958
 * null
959
 *
960
 * @param array|string|\Iterator $iterable
961
 * @param mixed $default
962
 * @return mixed
963
 * @deprecated Use iterable($iterable)->lastKey($default), will be removed in version 3.0
964
 */
965
function last_key($iterable, $default = null)
966
{
967
    if (!($iterable instanceof LastInterface)) {
968
        $iterable = iterable($iterable);
969
    }
970
971
    return $iterable->lastKey($default);
972
}
973
974
/**
975
 * Returns an FiniteIterableInterface, providing a fluent interface to itertools
976
 *
977
 * > iterable([1, 2, 3])->filter(...)->map(...)->first(...)
978
 *
979
 * @param array|string|\Iterator $iterable
980
 * @return FiniteIterableInterface
981
 */
982
function iterable($iterable)
983
{
984 425
    if ($iterable instanceof FiniteIterableInterface) {
985 2
        return $iterable;
986
    }
987
988 425
    return new IterableIterator(Conversions::mixedToIterator($iterable));
989
}
990