/** * Type representing a valid where operator. */ type WhereOperator = '&' | '>' | '>=' | '<' | '<=' | '!=' | '<=>' | '%' | '|' | '!' | '~' | '=' | '^' /** * Type associating search items with a key. */ type AssociatedSearchItem = { key: any, item: any } /** * Type representing the result of a where. */ type WhereResult = any[] /** * Returns true if the given item satisfies the given where clause. * @param {AssociatedSearchItem} item * @param {WhereOperator} operator * @param [operand] * @return boolean */ const whereMatch = (item: AssociatedSearchItem, operator: WhereOperator, operand?: unknown): boolean => { switch ( operator ) { case '&': if ( item.key & Number(operand) ) { return true } break case '>': if ( item.key > (operand as any) ) { return true } break case '>=': if ( item.key >= (operand as any) ) { return true } break case '<': if ( item.key < (operand as any) ) { return true } break case '<=': if ( item.key <= (operand as any) ) { return true } break case '!=': if ( item.key !== (operand as any) ) { return true } break case '<=>': if ( item.key === operand && typeof item.key !== 'undefined' && item.key !== null ) { return true } break case '%': if ( item.key % Number(operand) ) { return true } break case '|': if ( item.key | Number(operand) ) { return true } break case '!': if ( !item.key ) { return true } break case '~': if ( ~item.key ) { return true } break case '=': if ( item.key === operand ) { return true } break case '^': if ( item.key ^ Number(operand) ) { return true } break } return false } /** * Apply the given where clause to the items and return those that match. * @param {Array} items * @param {WhereOperator} operator * @param [operand] */ const applyWhere = (items: AssociatedSearchItem[], operator: WhereOperator, operand?: unknown): WhereResult => { const matches: WhereResult = [] for ( const item of items ) { if ( whereMatch(item, operator, operand) ) { matches.push(item.item) } } return matches } export { WhereOperator, WhereResult, AssociatedSearchItem, applyWhere, whereMatch }