quantitivecalc
Version:
A TypeScript library providing advanced quantitative finance functions for risk analysis, performance metrics, and technical indicators. (Currently in development)
119 lines (118 loc) • 5.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = analyzeColumnWithRange;
/**
* Analyzes items in a list based on a specified column and optional range constraints.
* Provides comprehensive information about extremes, range filtering, and statistical insights.
*
* @template T - The type of objects in the list.
* @template K - The key of the column to compare, must be a key of T with comparable values.
* @param list - The array of objects to search.
* @param columnName - The key of the column to analyze.
* @param minValue - Optional minimum value for range filtering.
* @param maxValue - Optional maximum value for range filtering.
* @param boundaryConfig - Configuration for boundary inclusion/exclusion behavior.
* @returns An object containing comprehensive analysis results.
*/
function analyzeColumnWithRange(list, columnName, minValue, maxValue, boundaryConfig = {}) {
// Default boundary behavior: inclusive for both min and max
const { minInclusive = true, maxInclusive = true } = boundaryConfig;
// Initialize result object
const result = {
min: undefined,
max: undefined,
itemsInRange: [],
itemsOutOfRange: [],
itemsBelowMin: [],
itemsAboveMax: [],
totalItems: list.length,
itemsInRangeCount: 0,
itemsOutOfRangeCount: 0,
percentageInRange: 0,
minInRange: undefined,
maxInRange: undefined,
isRangeValid: true,
rangeSpan: undefined,
itemsAtMinBoundary: [],
itemsAtMaxBoundary: [],
hasItemsInRange: false,
hasItemsOutOfRange: false,
allItemsInRange: false,
};
// Handle empty list
if (list.length === 0) {
return result;
}
// Validate range if both values are provided and not null
if (minValue !== undefined && minValue !== null && maxValue !== undefined && maxValue !== null) {
result.isRangeValid = minValue <= maxValue;
if (result.isRangeValid) {
// Calculate range span for numeric types
if (typeof minValue === 'number' && typeof maxValue === 'number') {
result.rangeSpan = (maxValue - minValue);
}
}
}
// Find basic extremes and analyze each item
let globalMin = list[0];
let globalMax = list[0];
let rangeMin = undefined;
let rangeMax = undefined;
for (const item of list) {
const value = item[columnName];
// Update global extremes
if (value < globalMin[columnName]) {
globalMin = item;
}
if (value > globalMax[columnName]) {
globalMax = item;
}
// Range analysis (only if range is valid or partially defined)
if (result.isRangeValid || minValue !== undefined || maxValue !== undefined) {
const isAboveMin = minValue === undefined || minValue === null || (minInclusive ? value >= minValue : value > minValue);
const isBelowMax = maxValue === undefined || maxValue === null || (maxInclusive ? value <= maxValue : value < maxValue);
const isInRange = isAboveMin && isBelowMax;
if (isInRange) {
result.itemsInRange.push(item);
// Track extremes within range
if (rangeMin == null || value < rangeMin[columnName]) {
rangeMin = item;
}
if (rangeMax == null || value > rangeMax[columnName]) {
rangeMax = item;
}
// Check for boundary items (only for inclusive boundaries)
if (minValue !== undefined && minInclusive && value === minValue) {
result.itemsAtMinBoundary.push(item);
}
if (maxValue !== undefined && maxInclusive && value === maxValue) {
result.itemsAtMaxBoundary.push(item);
}
}
else {
result.itemsOutOfRange.push(item);
// Categorize out-of-range items
if (minValue !== undefined && !isAboveMin) {
result.itemsBelowMin.push(item);
}
if (maxValue !== undefined && !isBelowMax) {
result.itemsAboveMax.push(item);
}
}
}
}
// Set basic extremes
result.min = globalMin;
result.max = globalMax;
result.minInRange = rangeMin;
result.maxInRange = rangeMax;
// Calculate statistics
result.itemsInRangeCount = result.itemsInRange.length;
result.itemsOutOfRangeCount = result.itemsOutOfRange.length;
result.percentageInRange = result.totalItems > 0 ? (result.itemsInRangeCount / result.totalItems) * 100 : 0;
// Set boolean flags
result.hasItemsInRange = result.itemsInRangeCount > 0;
result.hasItemsOutOfRange = result.itemsOutOfRangeCount > 0;
result.allItemsInRange = result.itemsInRangeCount === result.totalItems && result.totalItems > 0;
return result;
}