forked from maciejczyzewski/bottomline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreduce.php
111 lines (109 loc) · 2.51 KB
/
reduce.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
namespace collections;
/**
* Reduces `$collection` to a value which is the $accumulator result of running
* each element in `$collection` thru `$iteratee`, where each successive invocation
* is supplied the return value of the previous.
*
* If `$accumulator` is not given, the first element of `$collection` is used as
* the initial value.
*
* ## Sum Example
*
* **Usage**
*
* ```php
* __::reduce([1, 2], function ($accumulator, $value, $key, $collection) {
* return $accumulator + $value;
* }, 0);
* ```
*
* **Result**
*
* ```
* 3
* ```
*
* ## Array Counter
*
* **Usage**
*
* ```php
* $a = [
* ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'School bus'],
* ['state' => 'IN', 'city' => 'Indianapolis', 'object' => 'Manhole'],
* ['state' => 'IN', 'city' => 'Plainfield', 'object' => 'Basketball'],
* ['state' => 'CA', 'city' => 'San Diego', 'object' => 'Light bulb'],
* ['state' => 'CA', 'city' => 'Mountain View', 'object' => 'Space pen'],
* ];
*
* $iteratee = function ($accumulator, $value) {
* if (isset($accumulator[$value['city']]))
* $accumulator[$value['city']]++;
* else
* $accumulator[$value['city']] = 1;
* return $accumulator;
* };
*
* __::reduce($c, $iteratee, []);
* ```
*
* **Result**
*
* ```
* [
* 'Indianapolis' => 2,
* 'Plainfield' => 1,
* 'San Diego' => 1,
* 'Mountain View' => 1,
* ]
* ```
*
* ## Object Usage
*
* **Usage**
*
* ```php
* $object = new \stdClass();
* $object->a = 1;
* $object->b = 2;
* $object->c = 1;
*
* __::reduce($object, function ($result, $value, $key) {
* if (!isset($result[$value]))
* $result[$value] = [];
*
* $result[$value][] = $key;
*
* return $result;
* }, [])
* ```
*
* **Result**
*
* ```
* [
* '1' => ['a', 'c'],
* '2' => ['b']
* ]
* ```
*
* @param array|object $collection The collection to iterate over.
* @param \Closure $iteratee The function invoked per iteration.
* @param array|object|mixed $accumulator The initial value.
*
* @return array|object|mixed Returns the accumulated value.
*/
function reduce($collection, \Closure $iteratee, $accumulator = null)
{
if ($accumulator === null) {
$accumulator = \__::first($collection);
}
\__::doForEach(
$collection,
function ($value, $key, $collection) use (&$accumulator, $iteratee) {
$accumulator = $iteratee($accumulator, $value, $key, $collection);
}
);
return $accumulator;
}