/** * Sorts an array of items into groups. The return value is a map where the keys are * the group ids the given getGroupId function produced and the value is an array of * each item in that group. */ export const groupBy = ( array: readonly T[], getGroupId: (item: T) => Key ): Record => array.reduce((acc, item) => { const groupId = getGroupId(item); if (!acc[groupId]) acc[groupId] = []; acc[groupId].push(item); return acc; }, {} as Record); /** * Given a list of items returns a new list with only * unique items. Accepts an optional identity function * to convert each item in the list to a comparable identity * value */ export const unique = ( array: readonly T[], toKey?: (item: T) => K ): T[] => { const valueMap = array.reduce((acc, item) => { const key = toKey ? toKey(item) : (item as unknown as string | number | symbol); if (acc[key]) return acc; acc[key] = item; return acc; }, {} as Record); return Object.values(valueMap); };