agentsqripts
Version:
Comprehensive static code analysis toolkit for identifying technical debt, security vulnerabilities, performance issues, and code quality problems
76 lines (73 loc) • 3.28 kB
JavaScript
/**
* @file Count items by key with flexible key extraction
* @description Single responsibility: Count occurrences of items grouped by key
*
* This utility implements the classic "count by" functional programming pattern,
* providing flexible key extraction for statistical analysis and data aggregation.
* It supports both property-based and function-based key extraction for maximum
* flexibility across different use cases.
*
* Design rationale:
* - Supports both string property names and custom functions for key extraction
* - Uses reduce for efficient single-pass counting algorithm
* - Type checking enables dual interface (property vs function)
* - Object accumulator provides O(1) key lookup for performance
*/
/**
* Count array items grouped by specified key extraction method
*
* Technical function: Aggregates items into counts based on key extraction strategy
*
* Implementation rationale:
* - Type checking (typeof) enables dual interface for convenience and flexibility
* - Arrow function property accessor provides clean syntax for common use case
* - reduce() with object accumulator enables efficient single-pass counting
* - Logical OR (||) handles initialization of new keys gracefully
*
* Key extraction strategy:
* - String keyFn: Creates property accessor function (item) => item[keyFn]
* - Function keyFn: Uses provided function directly for custom logic
* - Supports any key type that can be used as object property
* - Handles missing properties by returning undefined as key
*
* Counting algorithm:
* - Single pass through items array using reduce
* - Object accumulator for O(1) key lookup and increment
* - Initializes new keys to 0 then increments to 1
* - Accumulates counts for duplicate keys efficiently
*
* Performance considerations:
* - O(n) time complexity for single pass through items
* - O(k) space complexity where k is number of unique keys
* - Object property access is O(1) for counting operations
* - Function call overhead minimal for key extraction
*
* Edge cases handled:
* - Empty items array: Returns empty object {}
* - Missing property access: Creates count for 'undefined' key
* - Function returning null/undefined: Creates count for those values
* - Duplicate keys: Properly accumulates counts
*
* Alternative approaches considered:
* - Map data structure: Rejected as objects serialize better for JSON output
* - forEach with external object: Rejected as less functional programming style
* - Separate functions for property vs function modes: Rejected for API simplicity
*
* @param {Array<any>} items - Array of items to count and group
* @param {Function|string} keyFn - Key extraction method:
* - String: Property name to extract from each item
* - Function: Custom function that takes item and returns key
* @returns {Object<string, number>} Object mapping keys to occurrence counts
* Example: { "severity": 3, "performance": 2, "security": 1 }
*/
function countBy(items, keyFn) {
const getKey = typeof keyFn === 'string'
? (item) => item[keyFn]
: keyFn;
return items.reduce((counts, item) => {
const key = getKey(item);
counts[key] = (counts[key] || 0) + 1;
return counts;
}, {});
}
module.exports = countBy;