import {groupValues} from '../internal/array/group'; import type {Key, KeyedValue, PlainObject, Simplify} from '../models'; // #region Functions /** * Create a record from an array of items using a specific key and value * * If multiple items have the same key, the latest item's value will be used * * @param array Array to group * @param key Callback to get an item's grouping key * @param value Callback to get an item's value * @returns Record of keyed values * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * item => item.value, * item => item, * ); // => {10: {id: 3, value: 10}, 20: {id: 2, value: 20}} * ``` */ export function groupBy< Item, KeyCallback extends (item: Item, index: number, array: Item[]) => Key, ValueCallback extends (item: Item, index: number, array: Item[]) => unknown, >( array: Item[], key: KeyCallback, value: ValueCallback, ): Simplify, ReturnType>>; /** * Create a record from an array of items using a specific key and value * * If multiple items have the same key, the latest item's value will be used * * @param array Array to group * @param key Callback to get an item's grouping key * @param value Key to use for value * @returns Record of keyed values * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * item => item.value, * 'id' * ); // => {10: 3, 20: 2} * ``` */ export function groupBy< Item extends PlainObject, KeyCallback extends (item: Item, index: number, array: Item[]) => Key, ItemValue extends keyof Item, >( array: Item[], key: KeyCallback, value: ItemValue, ): Record, Item[ItemValue]>; /** * Create a record from an array of items using a specific key and value * * If multiple items have the same key, the latest item's value will be used * * @param array Array to group * @param key Key to use for grouping * @param value Callback to get an item's value * @returns Record of keyed values * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * 'value', * item => item, * ); // => {10: {id: 3, value: 10}, 20: {id: 2, value: 20}} * ``` */ export function groupBy< Item extends PlainObject, ItemKey extends keyof Item, ValueCallback extends (item: Item, index: number, array: Item[]) => unknown, >( array: Item[], key: ItemKey, value: ValueCallback, ): Simplify, ReturnType>>; /** * Create a record from an array of items using a specific key and value * * If multiple items have the same key, the latest item's value will be used * * @param array Array to group * @param key Key to use for grouping * @param value Key to use for value * @returns Record of keyed values * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * 'value', * 'id' * ); // => {10: 3, 20: 2} * ``` */ export function groupBy< Item extends PlainObject, ItemKey extends keyof Item, ItemValue extends keyof Item, >( array: Item[], key: ItemKey, value: ItemValue, ): Simplify, Item[ItemValue]>>; /** * Create a record from an array of items using a specific key * * If multiple items have the same key, the latest item will be used * * @param array Array to group * @param callback Callback to get an item's grouping key * @returns Record of keyed items * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * item => item.value, * ); // => {10: {id: 3, value: 10}, 20: {id: 2, value: 20}} * ``` */ export function groupBy Key>( array: Item[], callback: Callback, ): Record, Item>; /** * Create a record from an array of items using a specific key * * If multiple items have the same key, the latest item will be used * * @param array Array to group * @param key Key to use for grouping * @returns Record of keyed items * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * 'value', * ); // => {10: {id: 3, value: 10}, 20: {id: 2, value: 20}} * ``` */ export function groupBy( array: Item[], key: ItemKey, ): Simplify, Item>>; /** * Create a record from an array of items _(using indices as keys)_ * * @param array Array to group * @returns Record of indiced items * * @example * ```typescript * groupBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * ); // => {0: {id: 1, value: 10}, 1: {id: 2, value: 20}, 2: {id: 3, value: 10}} * ``` */ export function groupBy(array: Item[]): Record; export function groupBy(array: unknown[], first?: unknown, second?: unknown): unknown { return groupValues(array, first, second, false); } groupBy.arrays = groupArraysBy; /** * Create a record from an array of items using a specific key and value, grouping values into arrays * * _Available as `groupArraysBy` and `groupBy.arrays`_ * * @param array Array to group * @param key Callback to get an item's grouping key * @param value Callback to get an item's value * @returns Record of keyed values * * @example * ```typescript * groupArraysBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * item => item.value, * item => item, * ); // => { * // 10: [{id: 1, value: 10}, {id: 3, value: 10}], * // 20: [{id: 2, value: 20}], * // } * ``` */ export function groupArraysBy< Item, KeyCallback extends (item: Item, index: number, array: Item[]) => Key, ValueCallback extends (item: Item, index: number, array: Item[]) => unknown, >( array: Item[], key: KeyCallback, value: ValueCallback, ): Record, ReturnType[]>; /** * Create a record from an array of items using a specific key and value, grouping values into arrays * * _Available as `groupArraysBy` and `groupBy.arrays`_ * * @param array Array to group * @param key Callback to get an item's grouping key * @param value Key to use for value * @returns Record of keyed values * * @example * ```typescript * groupArraysBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * item => item.value, * 'id', * ); // => { * // 10: [1, 3], * // 20: [2], * // } * ``` */ export function groupArraysBy< Item extends PlainObject, KeyCallback extends (item: Item, index: number, array: Item[]) => Key, ItemValue extends keyof Item, >( array: Item[], key: KeyCallback, value: ItemValue, ): Record, Item[ItemValue][]>; /** * Create a record from an array of items using a specific key and value, grouping values into arrays * * _Available as `groupArraysBy` and `groupBy.arrays`_ * * @param array Array to group * @param key Key to use for grouping * @param value Callback to get an item's value * @returns Record of keyed values * * @example * ```typescript * groupArraysBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * 'value', * item => item, * ); // => { * // 10: [{id: 1, value: 10}, {id: 3, value: 10}], * // 20: [{id: 2, value: 20}], * // } * ``` */ export function groupArraysBy< Item extends PlainObject, ItemKey extends keyof Item, ValueCallback extends (item: Item, index: number, array: Item[]) => unknown, >( array: Item[], key: ItemKey, value: ValueCallback, ): Simplify, ReturnType[]>>; /** * Create a record from an array of items using a specific key and value, grouping values into arrays * * _Available as `groupArraysBy` and `groupBy.arrays`_ * * @param array Array to group * @param key Key to use for grouping * @param value Key to use for value * @returns Record of keyed values * * @example * ```typescript * groupArraysBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * 'value', * 'id', * ); // => { * // 10: [1, 3], * // 20: [2], * // } * ``` */ export function groupArraysBy< Item extends PlainObject, ItemKey extends keyof Item, ItemValue extends keyof Item, >( array: Item[], key: ItemKey, value: ItemValue, ): Simplify, Item[ItemValue][]>>; /** * Create a record from an array of items using a specific key, grouping items into arrays * * _Available as `groupArraysBy` and `groupBy.arrays`_ * * @param array Array to group * @param callback Callback to get an item's grouping key * @returns Record of keyed items * * @example * ```typescript * groupArraysBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * item => item.value, * ); // => { * // 10: [{id: 1, value: 10}, {id: 3, value: 10}], * // 20: [{id: 2, value: 20}], * // } * ``` */ export function groupArraysBy< Item, Callback extends (item: Item, index: number, array: Item[]) => Key, >(array: Item[], callback: Callback): Record, Item[]>; /** * Create a record from an array of items using a specific key, grouping items into arrays * * _Available as `groupArraysBy` and `groupBy.arrays`_ * * @param array Array to group * @param key Key to use for grouping * @returns Record of keyed items * * @example * ```typescript * groupArraysBy( * [{id: 1, value: 10}, {id: 2, value: 20}, {id: 3, value: 10}], * 'value', * ); // => { * // 10: [{id: 1, value: 10}, {id: 3, value: 10}], * // 20: [{id: 2, value: 20}], * // } * ``` */ export function groupArraysBy( array: Item[], key: ItemKey, ): Simplify, Item[]>>; export function groupArraysBy(array: unknown[], first?: unknown, second?: unknown): unknown { return groupValues(array, first, second, true); } // #endregion