Completed
Push — master ( 7c9b2f...038cbf )
by Luke
32s
created

NumericCollection::prepareData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
nc 1
dl 0
loc 4
c 0
b 0
f 0
cc 1
eloc 2
nop 1
rs 10
1
<?php
2
3
/*
4
 * Nozavroni/Collections
5
 * Just another collections library for PHP5.6+.
6
 *
7
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
8
 * @author    Luke Visinoni <[email protected]>
9
 * @license   https://github.com/nozavroni/collections/blob/master/LICENSE The MIT License (MIT)
10
 */
11
namespace Noz\Collection;
12
13
use function Noz\is_traversable;
14
15
/**
16
 * Class NumericCollection.
17
 *
18
 * A collection that allows only numeric items, meaning only int, float, or numeric strings.
19
 *
20
 * @package Noz\Collection
21
 *
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
    /**
28
     * {@inheritdoc}
29
     */
30
    protected function prepareData($data)
31
    {
32
        return $data;
33
    }
34
35
    /**
36
     * Increment an item.
37
     *
38
     * Increment the item specified by $key by one value. Intended for integers
39
     * but also works (using this term loosely) for letters. Any other data type
40
     * it may modify is unintended behavior at best.
41
     *
42
     * This method modifies its internal data array rather than returning a new
43
     * collection.
44
     *
45
     * @param mixed $key      The key of the item you want to increment.
46
     * @param int   $interval The interval that $key should be incremented by
47
     *
48
     * @return $this
49
     */
50
    public function increment($key, $interval = 1)
51
    {
52
        $val = $this->get($key, null, true);
53
        for ($i = 0; $i < $interval; $i++) {
54
            $val++;
55
        }
56
        $this->set($key, $val);
57
58
        return $this;
59
    }
60
61
    /**
62
     * Decrement an item.
63
     *
64
     * Frcrement the item specified by $key by one value. Intended for integers.
65
     * Does not work for letters and if it does anything to anything else, it's
66
     * unintended at best.
67
     *
68
     * This method modifies its internal data array rather than returning a new
69
     * collection.
70
     *
71
     * @param mixed $key      The key of the item you want to decrement.
72
     * @param int   $interval The interval that $key should be decremented by
73
     *
74
     * @return $this
75
     */
76
    public function decrement($key, $interval = 1)
77
    {
78
        $val = $this->get($key, null, true);
79
        for ($i = 0; $i < $interval; $i++) {
80
            $val--;
81
        }
82
        $this->set($key, $val);
83
84
        return $this;
85
    }
86
87
    /**
88
     * Get the sum.
89
     *
90
     * @return mixed The sum of all values in collection
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use integer|double.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
91
     */
92
    public function sum()
93
    {
94
        return array_sum($this->toArray());
95
    }
96
97
    /**
98
     * Get the average.
99
     *
100
     * @return float|int The average value from the collection
101
     */
102
    public function average()
103
    {
104
        return $this->sum() / $this->count();
105
    }
106
107
    /**
108
     * Get the mode.
109
     *
110
     * @return float|int The mode
111
     */
112
    public function mode()
113
    {
114
        $counts = $this->counts()->toArray();
115
        arsort($counts);
116
        $mode = key($counts);
117
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
138
            return ($low + $high) / 2;
139
        }
140
        // odd number return median
141
        return $values[$middle];
142
    }
143
144
    /**
145
     * Get the maximum value.
146
     *
147
     * @return mixed The maximum
148
     */
149
    public function max()
150
    {
151
        return max($this->data);
152
    }
153
154
    /**
155
     * Get the minimum value.
156
     *
157
     * @return mixed The minimum
158
     */
159
    public function min()
160
    {
161
        return min($this->data);
162
    }
163
164
    /**
165
     * Get the number of times each item occurs in the collection.
166
     *
167
     * This method will return a NumericCollection where keys are the
168
     * values and values are the number of times that value occurs in
169
     * the original collection.
170
     *
171
     * @return NumericCollection
172
     */
173
    public function counts()
174
    {
175
        return new self(array_count_values($this->toArray()));
176
    }
177
178
    protected function isConsistentDataStructure($data)
179
    {
180
        if (!is_traversable($data)) {
181
            return false;
182
        }
183
        foreach ($data as $val) {
184
            if (!is_numeric($val)) {
185
                return false;
186
            }
187
        }
188
189
        return true;
190
    }
191
}
192