Completed
Pull Request — master (#170)
by Luke
02:40
created

NumericCollection::average()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * CSVelte: Slender, elegant CSV for PHP
4
 *
5
 * Inspired by Python's CSV module and Frictionless Data and the W3C's CSV
6
 * standardization efforts, CSVelte was written in an effort to take all the
7
 * suck out of working with CSV.
8
 *
9
 * @version   v${CSVELTE_DEV_VERSION}
10
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
11
 * @author    Luke Visinoni <[email protected]>
12
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
13
 */
14
namespace CSVelte\Collection;
15
16
use function CSVelte\is_traversable;
17
18
/**
19
 * Class NumericCollection
20
 *
21
 * @package CSVelte\Collection
22
 * @todo $this->set('foo', 'bar'); should throw an exception because only
23
 *     numeric values are allowed. Either that or converted to int.
24
 */
25
class NumericCollection extends AbstractCollection
26
{
27
    protected function isConsistentDataStructure($data)
28
    {
29
        if (!is_traversable($data)) {
30
            return false;
31
        }
32
        foreach ($data as $val) {
33
            if (!is_numeric($val)) {
34
                return false;
35
            }
36
        }
37
        return true;
38
    }
39
40
    /**
41
     * Increment an item.
42
     *
43
     * Increment the item specified by $key by one value. Intended for integers
44
     * but also works (using this term loosely) for letters. Any other data type
45
     * it may modify is unintended behavior at best.
46
     *
47
     * This method modifies its internal data array rather than returning a new
48
     * collection.
49
     *
50
     * @param  mixed $key The key of the item you want to increment.
51
     * @param int $interval The interval that $key should be incremented by
52
     * @return $this
53
     */
54
    public function increment($key, $interval = 1)
55
    {
56
        $val = $this->get($key, null, true);
57
        for ($i = 0; $i < $interval; $i++) {
58
            $val++;
59
        }
60
        $this->set($key, $val);
61
        return $this;
62
    }
63
64
    /**
65
     * Decrement an item.
66
     *
67
     * Frcrement the item specified by $key by one value. Intended for integers.
68
     * Does not work for letters and if it does anything to anything else, it's
69
     * unintended at best.
70
     *
71
     * This method modifies its internal data array rather than returning a new
72
     * collection.
73
     *
74
     * @param mixed $key The key of the item you want to decrement.
75
     * @param int $interval The interval that $key should be decremented by
76
     * @return $this
77
     */
78
    public function decrement($key, $interval = 1)
79
    {
80
        $val = $this->get($key, null, true);
81
        for ($i = 0; $i < $interval; $i++) {
82
            $val--;
83
        }
84
        $this->set($key, $val);
85
        return $this;
86
    }
87
88
    /**
89
     * Get the sum.
90
     *
91
     * @return mixed The sum of all values in collection
92
     */
93
    public function sum()
94
    {
95
        return array_sum($this->toArray());
96
    }
97
98
    /**
99
     * Get the average.
100
     *
101
     * @return float|int The average value from the collection
102
     */
103
    public function average()
104
    {
105
        return $this->sum() / $this->count();
106
    }
107
108
    /**
109
     * Get the mode.
110
     *
111
     * @return float|int The mode
112
     */
113
    public function mode()
114
    {
115
        $counts = $this->counts()->toArray();
116
        arsort($counts);
117
        $mode = key($counts);
118
        return (strpos($mode, '.')) ? floatval($mode) : intval($mode);
119
    }
120
121
    /**
122
     * Get the median value.
123
     *
124
     * @return float|int The median value
125
     */
126
    public function median()
127
    {
128
        $count = $this->count();
129
        $data = $this->toArray();
130
        natcasesort($data);
131
        $middle = $count / 2;
132
        $values = array_values($data);
133
        if ($count % 2 == 0) {
134
            // even number, use middle
135
            $low = $values[$middle - 1];
136
            $high = $values[$middle];
137
            return ($low + $high) / 2;
138
        }
139
        // odd number return median
140
        return $values[$middle];
141
    }
142
143
    /**
144
     * Get the maximum value.
145
     *
146
     * @return mixed The maximum
147
     */
148
    public function max()
149
    {
150
        return max($this->data);
151
    }
152
153
    /**
154
     * Get the minimum value.
155
     *
156
     * @return mixed The minimum
157
     */
158
    public function min()
159
    {
160
        return min($this->data);
161
    }
162
163
    /**
164
     * Get the number of times each item occurs in the collection.
165
     *
166
     * This method will return a NumericCollection where keys are the
167
     * values and values are the number of times that value occurs in
168
     * the original collection.
169
     *
170
     * @return NumericCollection
171
     */
172
    public function counts()
173
    {
174
        return new self(array_count_values($this->toArray()));
175
    }
176
177
}