-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
ComplexMetric.ts
249 lines (225 loc) · 7.7 KB
/
ComplexMetric.ts
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
import { AbstractMetric } from './AbstractMetric';
import { MetricValue, BasicInsightsMetricData } from './BasicInsightsMetricData';
/**
* Type to represent a complex metric value.
*
* @author Tiago Grosso <tiagogrosso99@gmail.com>
* @since 0.2.0
*/
export type ComplexMetricValue = { [key: string]: number };
/**
* Class to represent a complex metric.
*
* As a metric class, it expects to receive an array of values.
* However, for complex metrics that array has a single element.
* This class assumes that to always be true to simplify the access the values.
*
* @author Tiago Grosso <tiagogrosso99@gmail.com>
* @since 0.1.0
*/
export class ComplexMetric extends AbstractMetric<MetricValue<ComplexMetricValue>[]> {
/**
* The value.
*/
private value: ComplexMetricValue;
/**
* The end time.
*/
private endTime: Date;
/**
* The constructor.
*
* @param data the metric data.
*/
constructor(data: BasicInsightsMetricData<MetricValue<ComplexMetricValue>[]>) {
super(data);
this.value = this.metricData.values[0].value;
this.endTime = new Date(this.metricData.values[0].end_time);
}
/**
* Gets the value of the metric.
*
* @returns the value of the metric.
*/
public getValue(): ComplexMetricValue {
return this.value;
}
/**
* Gets the end time of the metric value.
*
* @returns the end time of the metric value.
*/
public getEndTime(): Date {
return this.endTime;
}
/**
* Gets the keys that match the provided expression.
*
* @param expression expression to match the values to.
*
* @returns the keys that match the provided expression.
*/
public getKeysByExpression(expression: (pair: [key: string, value: number]) => boolean): string[] {
return Object.entries(this.value)
.filter(expression)
.map(([key]) => key);
}
/**
* Gets the keys of the values that are greater than the provided limit.
*
* @param limit the limit.
*
* @returns the keys of the values that are greater than the provided limit.
*/
public getKeysByGreaterThan(limit: number): string[] {
return this.getKeysByExpression(([, value]) => value > limit);
}
/**
* Gets the keys of the values that are greater than or equal to the provided limit.
*
* @param limit the limit.
*
* @returns the keys of the values that are greater than or equal to the provided limit.
*/
public getKeysByGreaterThanOrEqualTo(limit: number): string[] {
return this.getKeysByExpression(([, value]) => value >= limit);
}
/**
* Gets the keys of the values that are smaller than to the provided limit.
*
* @param limit the limit.
*
* @returns the keys of the values that are smaller than to the provided limit.
*/
public getKeysByLessThan(limit: number): string[] {
return this.getKeysByExpression(([, value]) => value < limit);
}
/**
* Gets the keys of the values that are smaller than or equal to the provided limit.
*
* @param limit the limit.
*
* @returns the keys of the values that are smaller than or equal to the provided limit.
*/
public getKeysByLessThanOrEqualTo(limit: number): string[] {
return this.getKeysByExpression(([, value]) => value <= limit);
}
/**
* Gets the keys of the values that are equal to the provided value.
*
* @param valueToCompare the value to compare to.
*
* @returns the keys of the values that are equal to the provided value.
*/
public getKeysByEqualTo(valueToCompare: number): string[] {
return this.getKeysByExpression(([, value]) => value === valueToCompare);
}
/**
* Gets the entries that match the provided expression.
*
* @param expression expression to match the values to.
*
* @returns the entries that match the provided expression.
*/
public getByExpression(expression: (pair: [key: string, value: number]) => boolean): ComplexMetricValue {
const filtered: ComplexMetricValue = {};
Object.entries(this.value)
.filter(expression)
.forEach(([key, value]) => (filtered[key] = value));
return filtered;
}
/**
* Gets the entries of the values that are greater than the provided limit.
*
* @param limit the limit.
*
* @returns the entries of the values that are greater than the provided limit.
*/
public getByGreaterThan(limit: number): ComplexMetricValue {
return this.getByExpression(([, value]) => value > limit);
}
/**
* Gets the entries of the values that are greater than or equal to the provided limit.
*
* @param limit the limit.
*
* @returns the entries of the values that are greater than or equal to the provided limit.
*/
public getByGreaterThanOrEqualTo(limit: number): ComplexMetricValue {
return this.getByExpression(([, value]) => value >= limit);
}
/**
* Gets the entries of the values that are equal than the provided limit.
*
* @param limit the limit.
*
* @returns the entries of the values that are equal than the provided limit.
*/
public getByLessThan(limit: number): ComplexMetricValue {
return this.getByExpression(([, value]) => value < limit);
}
/**
* Gets the entries of the values that are greater than or equal to the provided limit.
*
* @param limit the limit.
*
* @returns the entries of the values that are greater than or equal to the provided limit.
*/
public getByLessThanOrEqualTo(limit: number): ComplexMetricValue {
return this.getByExpression(([, value]) => value <= limit);
}
/**
* Gets the entries of the provided keys.
*
* @param limit the limit.
*
* @returns the entries of the provided keys.
*/
public getByKeys(...keys: string[]): ComplexMetricValue {
return this.getByExpression(([key]) => keys.includes(key));
}
/**
* Returns the highest value of the metric. In case of a tie, the first value found is returned.
*
* @returns the highest value of the metric.
*/
public getHighest(): { key: string; value: number } | undefined {
let highest: { key: string; value: number } | undefined;
Object.entries(this.value).forEach(([key, value]) => {
if (highest == undefined || value > highest.value) {
highest = { key: key, value: value };
}
});
return highest;
}
/**
* Returns the key of the highest value of the metric. In case of a tie, the key of the first value found is returned.
*
* @returns the key of highest value of the metric.
*/
public getHighestKey(): string | undefined {
return this.getHighest()?.key;
}
/**
* Returns the highest value of the metric. In case of a tie, the first value found is returned.
*
* @returns the highest value of the metric.
*/
public getLowest(): { key: string; value: number } | undefined {
let lowest: { key: string; value: number } | undefined;
Object.entries(this.value).forEach(([key, value]) => {
if (lowest == undefined || value < lowest.value) {
lowest = { key: key, value: value };
}
});
return lowest;
}
/**
* Returns the key of the lowest value of the metric. In case of a tie, the key of the first value found is returned.
*
* @returns the key of lowest value of the metric.
*/
public getLowestKey(): string | undefined {
return this.getLowest()?.key;
}
}