1 module onsdata.rows;
2 
3 import std.conv;
4 import onsdata;
5 
6 void min(T)(Row!T[] rows, size_t target, size_t[] cols) {
7 	foreach(row; rows) row.min(target, cols);
8 }
9 
10 /+ avg - returns the average value of columns in rows and write the result in the target col of each row +/
11 void avg(T)(Row!T[] rows, size_t target, size_t[] cols) { foreach(row; rows) row.avg(target, cols); }
12 /+ avg - returns the average value of columns in selected rows +/
13 S avg(S = double, T)(Row!T[] rows, size_t target) {
14 	size_t counter = 0;
15 	double sum = 0;
16 	foreach(row; rows) if (row) {
17 		counter++;
18 		sum += row[target];
19 	}
20 	if (counter) return to!S(sum/counter);
21 	return 0;
22 }
23 /*
24 AVG
25 S avg(S = double, T)(T[][] table, size_t col, size_t start = 0, size_t end = size_t.max) {
26 	return (end == size_t.max) ? avg(table[start..table.length], col) : avg(table[start..end], col) ;
27 }
28 S avg(S = double, T)(T[][] table, size_t col) {
29 	int counter = 0; double sum = 0;
30 	foreach(row; table) if (row) { counter++; sum += row[col]; }
31 	return (counter) ? sum/counter : 0;
32 }
33 */
34 void max(T)(Row!T[] rows, size_t target, size_t[] cols) {
35 	foreach(row; rows) row.max(target, cols);
36 }
37 void sum(T)(Row!T[] rows, size_t target, size_t[] cols) {
38 	foreach(row; rows) row.sum(target, cols);
39 }
40 void delta(T)(Row!T[] rows, size_t target, size_t[2] cols) {
41 	foreach(row; rows) row.delta(target, cols);
42 }
43 
44 T min(T)(Row!T[] rows, size_t col) if (isNumeric!T) {
45 	bool first = false;
46 	T result = 0;
47 	foreach(row; rows) {
48 		if (row) {
49 			if (!first) {
50 				result = row[col];
51 				first = true;
52 			}
53 			else {
54 				if (result > row[col]) result = row[col];
55 			}
56 		}
57 	}
58 	return result;
59 }
60 
61 T max(T)(Row!T[] rows, size_t col) if (isNumeric!T) {
62 	bool first = false;
63 	T result = 0;
64 	foreach(row; rows) {
65 		if (row) {
66 			if (!first) {
67 				result = row[col];
68 				first = true;
69 			}
70 			else {
71 				if (result < row[col]) result = row[col];
72 			}
73 		}
74 	}
75 	return result;
76 }
77 
78 void delta(T)(Row!T[] rows, size_t target, size_t[2] cols) { table.delta(target, cols[0], cols[1]); }
79 void delta(T)(Row!T[] rows, size_t target, size_t left, size_t right) { 
80 	foreach(row; table) if (row) {
81 		if (!target.inside(row)) return;
82 		if (!left.inside(row)) return;
83 		if (!right.inside(row)) return;
84 		
85 		row[target] = row[right] - row[left];
86 	}
87 }
88 
89 double inc(T)(Row!T[] rows, size_t col) {
90 	int counter = 0; int x = 0; bool foundFirst = false;
91 	foreach(i, row; rows) if (row) {
92 		if (i == 0) continue;
93 		
94 		if ((foundFirst) && (rows[i-1])) {
95 			double delta = row[col] - rows[i-1][col];
96 			if (delta > 0) x++;
97 			counter++;
98 		}
99 		else foundFirst = true;
100 	}
101 	if (counter) return x/counter;
102 	return 0;
103 }
104 double dec(T)(Row!T[] rows, size_t col) {
105 	int counter = 0; int x = 0; bool foundFirst = false;
106 	foreach(i, row; rows) if (row) {
107 		if (i == 0) continue;
108 		
109 		if ((foundFirst) && (rows[i-1])) {
110 			double delta = row[col] - rows[i-1][col];
111 			if (delta < 0) x++;
112 			counter++;
113 		}
114 		else foundFirst = true;
115 	}
116 	if (counter) return x/counter;
117 	return 0;
118 }
119 
120 S sum(S = double, T)(size_t col) { 
121 	double result = 0;
122 	foreach(row; rows) if (row) result += row[col];
123 	return to!S(result);
124 }
125 S sum(S = double, T)(Row!T rows, size_t col, size_t start = 0, size_t end = size_t.max) {
126 	int counter = 0; double sum = 0;
127 	if (end > rows.length) end = rows.length;
128 	foreach(i; start..end) if (auto row = table[i]) { counter++; sum += row[col]; }
129 	return To!S((counter) ? sum/counter : 0);
130 }
131 
132 
133 
134 
135 // -- getInc
136 double getInc(T)(T[][] table, size_t col){
137 	int counter = 0; int x = 0; bool foundFirst = false;
138 	foreach(i, row; table) if (row) {
139 		if (i == 0) continue;
140 		
141 		if ((foundFirst) && (table[i-1])) {
142 			double delta = row[col] - table[i-1][col];
143 			if (delta > 0) x++;
144 			counter++;
145 		}
146 		else foundFirst = true;
147 	}
148 	if (counter) return x/counter;
149 	return 0;
150 }
151 
152 // AVG
153 bool Avg(T)(T[][] table, size_t target, size_t[] cols, size_t start = 0, size_t end = size_t.max) { 
154 	return (end == size_t.max) ? setAvg(table[start..table.length], target, cols) : setAvg(table[start..end], target, cols);
155 }
156 bool Avg(T)(T[][] table, size_t target, size_t[] cols) { 
157 	if (table.length == 0) return false;
158 	if (cols.length == 0) return false;
159 	
160 	auto rlen = table[0].length-1; // max Value
161 	if (target > rlen) return false;
162 	foreach(col; cols) if (col > rlen) return false;
163 	
164 	double colSum = row[cols[0]];
165 	foreach(row; table) if (row) {
166 		if (cols.length > 1) foreach(col; cols[1..$]) colSum += row[col];
167 		row[target] = check!T(colSum/cols.length);
168 	}
169 	return true;
170 }
171 
172 size_t count(T)(T[][] table, size_t left, Ops op, T right) if (isBasicType!T)
173 in {
174 	assert(((op == op.GC) || (op == op.LC)) && (right >= 0));
175 }
176 body {	
177 	import std.conv;
178 	size_t result = 0;  size_t rCol;
179 	if ((op == op.GC) || (op == op.LC)) rCol = to!size_t(right);
180 	
181 	foreach(row; table) if (row) {
182 		final switch(op) {
183 			case Ops.GC: if (row[left] > row[rCol]) result++; break;
184 			case Ops.LC: if (row[left] < row[rCol]) result++; break;
185 			case Ops.GV: if (row[left] > right) result++; break;
186 			case Ops.LV: if (row[left] < right) result++; break;
187 		}
188 	}
189 	return result;
190 }
191 
192 T[][] find(T, S)(T[][] table, size_t left, Ops op, S right) if (isBasicType!T)
193 in {
194 	assert(((op == op.GC) || (op == op.LC)) && (right >= 0));
195 }
196 body {	
197 	import std.conv;
198 	T[][] result;  size_t rCol;
199 	if ((op == op.GC) || (op == op.LC)) rCol = to!size_t(right);
200 	
201 	foreach(row; table) if (row) {
202 		final switch(op) {
203 			case Ops.GC: if (row[left] > row[rCol]) result ~= row; break;
204 			case Ops.LC: if (row[left] < row[rCol]) result ~= row; break;
205 			case Ops.GV: if (row[left] > right) result ~= row; break;
206 			case Ops.LV: if (row[left] < right) result ~= row; break;
207 		}
208 	}
209 	return result;
210 }