NumericCollection   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 159
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 1

Importance

Changes 0
Metric Value
dl 0
loc 159
rs 10
c 0
b 0
f 0
wmc 17
lcom 3
cbo 1

10 Methods

Rating   Name   Duplication   Size   Complexity  
A increment() 0 10 2
A decrement() 0 10 2
A sum() 0 4 1
A average() 0 4 1
A mode() 0 8 2
A median() 0 17 2
A max() 0 4 1
A min() 0 4 1
A counts() 0 4 1
A isConsistentDataStructure() 0 13 4
1
<?php
2
3
/*
4
 * CSVelte: Slender, elegant CSV for PHP
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   {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
 *
23
 * @todo $this->set('foo', 'bar'); should throw an exception because only
24
 *     numeric values are allowed. Either that or converted to int.
25
 */
26
class NumericCollection extends AbstractCollection
27
{
28
    /**
29
     * Increment an item.
30
     *
31
     * Increment the item specified by $key by one value. Intended for integers
32
     * but also works (using this term loosely) for letters. Any other data type
33
     * it may modify is unintended behavior at best.
34
     *
35
     * This method modifies its internal data array rather than returning a new
36
     * collection.
37
     *
38
     * @param mixed $key      The key of the item you want to increment.
39
     * @param int   $interval The interval that $key should be incremented by
40
     *
41
     * @return $this
42
     */
43
    public function increment($key, $interval = 1)
44
    {
45
        $val = $this->get($key, null, true);
46
        for ($i = 0; $i < $interval; $i++) {
47
            $val++;
48
        }
49
        $this->set($key, $val);
50
51
        return $this;
52
    }
53
54
    /**
55
     * Decrement an item.
56
     *
57
     * Frcrement the item specified by $key by one value. Intended for integers.
58
     * Does not work for letters and if it does anything to anything else, it's
59
     * unintended at best.
60
     *
61
     * This method modifies its internal data array rather than returning a new
62
     * collection.
63
     *
64
     * @param mixed $key      The key of the item you want to decrement.
65
     * @param int   $interval The interval that $key should be decremented by
66
     *
67
     * @return $this
68
     */
69
    public function decrement($key, $interval = 1)
70
    {
71
        $val = $this->get($key, null, true);
72
        for ($i = 0; $i < $interval; $i++) {
73
            $val--;
74
        }
75
        $this->set($key, $val);
76
77
        return $this;
78
    }
79
80
    /**
81
     * Get the sum.
82
     *
83
     * @return mixed The sum of all values in collection
84
     */
85
    public function sum()
86
    {
87
        return array_sum($this->toArray());
88
    }
89
90
    /**
91
     * Get the average.
92
     *
93
     * @return float|int The average value from the collection
94
     */
95
    public function average()
96
    {
97
        return $this->sum() / $this->count();
98
    }
99
100
    /**
101
     * Get the mode.
102
     *
103
     * @return float|int The mode
104
     */
105
    public function mode()
106
    {
107
        $counts = $this->counts()->toArray();
108
        arsort($counts);
109
        $mode = key($counts);
110
111
        return (strpos($mode, '.')) ? floatval($mode) : intval($mode);
112
    }
113
114
    /**
115
     * Get the median value.
116
     *
117
     * @return float|int The median value
118
     */
119
    public function median()
120
    {
121
        $count = $this->count();
122
        $data  = $this->toArray();
123
        natcasesort($data);
124
        $middle = $count / 2;
125
        $values = array_values($data);
126
        if ($count % 2 == 0) {
127
            // even number, use middle
128
            $low  = $values[$middle - 1];
129
            $high = $values[$middle];
130
131
            return ($low + $high) / 2;
132
        }
133
        // odd number return median
134
        return $values[$middle];
135
    }
136
137
    /**
138
     * Get the maximum value.
139
     *
140
     * @return mixed The maximum
141
     */
142
    public function max()
143
    {
144
        return max($this->data);
145
    }
146
147
    /**
148
     * Get the minimum value.
149
     *
150
     * @return mixed The minimum
151
     */
152
    public function min()
153
    {
154
        return min($this->data);
155
    }
156
157
    /**
158
     * Get the number of times each item occurs in the collection.
159
     *
160
     * This method will return a NumericCollection where keys are the
161
     * values and values are the number of times that value occurs in
162
     * the original collection.
163
     *
164
     * @return NumericCollection
165
     */
166
    public function counts()
167
    {
168
        return new self(array_count_values($this->toArray()));
169
    }
170
171
    protected function isConsistentDataStructure($data)
172
    {
173
        if (!is_traversable($data)) {
174
            return false;
175
        }
176
        foreach ($data as $val) {
177
            if (!is_numeric($val)) {
178
                return false;
179
            }
180
        }
181
182
        return true;
183
    }
184
}
185