export type FilterFunction = (o: T) => boolean export type MapperFunction = (o: T) => any /** Apply multiple filters, optionally transform through mappers, filter null/undefined items. */ export function listQuery( list: T[], filters: FilterFunction[], mappers: MapperFunction[] = [], ): T | any[] { return list .filter((o: T) => !filters.some(a => !a(o))) .map((o) => { for (const m of mappers) o = m(o) return o }) .filter(o => o != null) } /** Split up a list by `key` resulting in a Record of `key` and sub-list. */ export function listGroupBy>( list: T[], key: keyof T, ): Record { return list.reduce((result: any, currentValue: T) => { const groupValue = String(currentValue[key]) ;(result[groupValue] = result[groupValue] || []).push(currentValue) return result }, {}) } /** Returns a list of values of a certain `key`. No duplicates. */ export function listDistinctUnion>( list: T[], key: keyof T, ): any[] { return Array.from( list.reduce( (result: Set, currentValue: T) => result.add(currentValue[key]), new Set(), ), ) } /** Returns a list of values of a certain `key`. */ export function listOfKey>( list: T[], key: keyof T, ): any[] { return list.map(item => item[key]) }