You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
lib/src/util/collection/where.ts

113 lines
2.6 KiB

/**
* 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<AssociatedSearchItem>} 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 }