UNPKG

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
"use strict"; 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; }