-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
104 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
export const groupBy = <T>(data: T[], prop: Extract<keyof T, string>): Record<keyof T, T[]> => { | ||
const result = {} as Record<keyof T, T[]>; | ||
data.forEach((item) => { | ||
const key = String(item[prop]) as keyof T; | ||
if (!result[key]) { | ||
result[key] = []; | ||
} | ||
result[key].push(item); | ||
}); | ||
return result; | ||
}; | ||
|
||
export const aggregate = <T, U>(data: T[], prop: Extract<keyof T, string>, map: (x: T[]) => U): Record<keyof T, U> => { | ||
const result = {} as Record<keyof T, U>; | ||
const grouped = groupBy(data, prop); | ||
Object.keys(grouped).forEach((key) => { | ||
result[key as keyof T] = map(grouped[key as keyof T]); | ||
}); | ||
|
||
return result; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import crypto from 'crypto'; | ||
|
||
export const getSimpleHash = (obj: unknown) => { | ||
if (obj === undefined) throw new Error('Object is undefined'); | ||
|
||
const objString = JSON.stringify(obj); | ||
return crypto.createHash('sha256').update(objString).digest('hex'); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { groupBy, aggregate } from '../src/groupBy'; | ||
|
||
describe('groupBy', () => { | ||
it('should group an array of objects by a given property', () => { | ||
const data = [ | ||
{ id: 1, name: 'John' }, | ||
{ id: 2, name: 'Jane' }, | ||
{ id: 3, name: 'John' }, | ||
{ id: 4, name: 'Jane' }, | ||
]; | ||
|
||
const result = groupBy(data, 'name'); | ||
|
||
expect(result).toEqual({ | ||
John: [ | ||
{ id: 1, name: 'John' }, | ||
{ id: 3, name: 'John' }, | ||
], | ||
Jane: [ | ||
{ id: 2, name: 'Jane' }, | ||
{ id: 4, name: 'Jane' }, | ||
], | ||
}); | ||
}); | ||
}); | ||
|
||
describe('aggregate', () => { | ||
it('should group an array of objects by a given property and apply a map function', () => { | ||
const data = [ | ||
{ id: 1, name: 'John', age: 30 }, | ||
{ id: 2, name: 'Jane', age: 25 }, | ||
{ id: 3, name: 'John', age: 35 }, | ||
{ id: 4, name: 'Jane', age: 40 }, | ||
]; | ||
|
||
const result = aggregate(data, 'name', (group) => { | ||
const totalAge = group.reduce((acc, curr) => acc + curr.age, 0); | ||
const averageAge = totalAge / group.length; | ||
|
||
return { totalAge, averageAge }; | ||
}); | ||
|
||
expect(result).toEqual({ | ||
John: { totalAge: 65, averageAge: 32.5 }, | ||
Jane: { totalAge: 65, averageAge: 32.5 }, | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { getSimpleHash } from '../src/simpleHash'; | ||
|
||
describe('getSimpleHash', () => { | ||
it('should return a string', () => { | ||
const result = getSimpleHash('test'); | ||
expect(typeof result).toBe('string'); | ||
}); | ||
|
||
it('should return the same hash for the same input', () => { | ||
const input = { name: 'John', age: 30 }; | ||
const result1 = getSimpleHash(input); | ||
const result2 = getSimpleHash(input); | ||
expect(result1).toBe(result2); | ||
}); | ||
|
||
it('should return different hashes for different inputs', () => { | ||
const input1 = { name: 'John', age: 30 }; | ||
const input2 = { name: 'Jane', age: 25 }; | ||
const result1 = getSimpleHash(input1); | ||
const result2 = getSimpleHash(input2); | ||
expect(result1).not.toBe(result2); | ||
}); | ||
|
||
it('should fail if input is undefined', () => { | ||
expect(() => getSimpleHash(undefined)).toThrowError('Object is undefined'); | ||
}); | ||
}); |