modeBy
Returns the most frequent item in an array based on a selector function. If there are multiple items with the same frequency, returns the first one encountered.
1/**
2 * Returns the most frequent item in an array based on a selector function.
3 * If there are multiple items with the same frequency, returns the first one encountered.
4 *
5 * @param arr - The input array.
6 * @param fn - A function that returns a comparable key for each item.
7 * @returns The most frequent item based on the selected key, or undefined if the array is empty.
8 */
9export function modeBy<T>(arr: T[], fn: (item: T) => string | number): T | undefined {
10 const counts = new Map<string | number, { count: number; item: T }>();
11
12 for (const item of arr) {
13 const key = fn(item);
14 if (!counts.has(key)) {
15 counts.set(key, { count: 1, item });
16 } else {
17 counts.get(key)!.count++;
18 }
19 }
20
21 let maxCount = -1;
22 let result: T | undefined;
23
24 for (const { count, item } of counts.values()) {
25 if (count > maxCount) {
26 maxCount = count;
27 result = item;
28 }
29 }
30
31 return result;
32}
Custom Key Selection
Supports complex data structures by allowing users to define how grouping is performed via a selector function.
Efficient Frequency Counting
Uses a
Map
to efficiently track frequencies without repeated array scans.Stable Result on Ties
Returns the first encountered item in case of frequency ties, which provides deterministic behavior.
Type-Safe and Generic
Maintains full item type and structure while supporting flexible selector outputs (string or number).
Graceful Handling of Empty Arrays
Returns
undefined
when the input is empty, avoiding exceptions or ambiguous results.
Tests | Examples
1test('modeBy - returns most frequent by key', () => {
2 const data = [
3 { name: 'a' },
4 { name: 'b' },
5 { name: 'a' },
6 { name: 'c' },
7 { name: 'b' },
8 { name: 'a' },
9 ];
10 expect(modeBy(data, x => x.name)).toEqual({ name: 'a' });
11});
12
13test('modeBy - ties return first encountered', () => {
14 const data = [
15 { id: 1 }, { id: 2 }, { id: 2 }, { id: 1 }
16 ];
17 expect(modeBy(data, x => x.id)).toEqual({ id: 1 }); // 1 and 2 both occur twice
18});
19
20test('modeBy - works with numbers', () => {
21 expect(modeBy([1, 2, 2, 3, 1, 2], x => x)).toBe(2);
22});
23
24test('modeBy - empty array returns undefined', () => {
25 expect(modeBy([], x => x)).toBeUndefined();
26});
Common Use Cases
Identifying Most Common Value
Determine the most frequently occurring category, tag, or label in a dataset.
User Behavior Analysis
Find the most visited page, clicked item, or frequent action from logs or events.
Recommendation Systems
Surface the most common user preferences, selections, or interactions.
Data Cleaning & Deduplication
Infer dominant values to fill missing or inconsistent fields.
Voting or Polling Systems
Determine the most selected option in a list of responses.