Skip to content

Commit

Permalink
add array groupBy function
Browse files Browse the repository at this point in the history
  • Loading branch information
andrej-dyck committed Oct 17, 2024
1 parent e5b7279 commit 7bd2cc2
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 410 deletions.
27 changes: 27 additions & 0 deletions arrays/groupBy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { describe, expect, test } from 'vitest'
import { groupBy } from './groupBy.ts'

describe('array groupBy', () => {

test('empty array', () => {
expect(groupBy([], () => 'p')).toEqual({})
})

test('selecting to same property', () => {
expect(groupBy([1, 2, 3], () => 'p')).toEqual({
p: [1, 2, 3],
})
})

test('group array of objects by property key', () => {
expect(
groupBy(
[{ id: '1', value: 1 }, { id: '2', value: 2 }, { id: '1', value: 3 }],
(item) => item.id
)
).toEqual({
1: [{ id: '1', value: 1 }, { id: '1', value: 3 }],
2: [{ id: '2', value: 2 }],
})
})
})
23 changes: 23 additions & 0 deletions arrays/groupBy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { NonEmptyArray } from '../types/index.js'

export type Grouping<T> = Record<PropertyKey, NonEmptyArray<T>>

/**
* Groups an array of items by a property-key
* Example:
* groupBy(
* [{ id: "1", value: 1 },{ id: "2", value: 2 },{ id: "1", value: 3 }],
* (item) => item.id
* ) === {
* 1: [{ id: "1", value: 1 },{ id: "1", value: 3 }],
* 2: [{ id: "2", value: 2 }]
* }
*/
export const groupBy = <T>(array: readonly T[], keySelector: (item: T) => PropertyKey): Grouping<T> =>
array.reduce<Grouping<T>>((group, item) => {
const key = keySelector(item)
return {
...group,
[key]: group[key] == null ? <NonEmptyArray<T>>[item] : <NonEmptyArray<T>>[...group[key], item],
}
}, {})
Empty file added arrays/index.ts
Empty file.
10 changes: 3 additions & 7 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default tseslint.config(
'exports': 'only-multiline',
'functions': 'never',
}],
'space-before-blocks': ['warn'],
'space-unary-ops': ['warn'],
'consistent-return': ['warn'],
'eol-last': ['warn'],
Expand All @@ -43,16 +44,11 @@ export default tseslint.config(

/* typescript */
'@typescript-eslint/consistent-type-definitions': 'off',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/consistent-type-assertions': 'off',
'@typescript-eslint/no-confusing-void-expression': ['error', { ignoreArrowShorthand: true }],
'@typescript-eslint/no-unused-vars': 'off', // enforced by tsconfig
'@typescript-eslint/prefer-readonly': ['warn'],
'@typescript-eslint/space-before-blocks': ['error'],
'@typescript-eslint/switch-exhaustiveness-check': ['warn'],
'@typescript-eslint/type-annotation-spacing': ['error', {
before: false,
after: true,
overrides: { arrow: { before: true, after: true } },
}],
},
},
{
Expand Down
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './arrays/index.ts'
export * from './events/index.ts'
export * from './json/index.ts'
export * from './lazy/index.ts'
Expand Down
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
"engines": {
"npm": "please-use-pnpm",
"yarn": "please-use-pnpm",
"pnpm": ">=9.5.0"
"pnpm": ">=9.12.0"
},
"devDependencies": {
"@eslint/js": "9.7.0",
"@types/node": "20.14.11",
"eslint": "9.7.0",
"typescript": "5.5.3",
"typescript-eslint": "7.16.1",
"vitest": "2.0.3",
"@eslint/js": "9.12.0",
"@types/node": "22.7.6",
"eslint": "9.12.0",
"typescript": "5.6.3",
"typescript-eslint": "8.9.0",
"vitest": "2.1.3",
"zod": "3.23.8"
}
}
Loading

0 comments on commit 7bd2cc2

Please sign in to comment.