@gabrielrufino/cerebrum 2.0.7 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupBy = void 0;
4
+ class GroupBy {
5
+ constructor(items, key) {
6
+ this.items = items;
7
+ this.key = key;
8
+ }
9
+ execute() {
10
+ return this.items.reduce((accumulator, item) => {
11
+ const group = item[this.key];
12
+ if (!accumulator[group]) {
13
+ accumulator[group] = [];
14
+ }
15
+ accumulator[group].push(item);
16
+ return accumulator;
17
+ }, {});
18
+ }
19
+ }
20
+ exports.GroupBy = GroupBy;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./GroupBy"), exports);
package/dist/index.js CHANGED
@@ -33,7 +33,8 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.Sort = exports.Search = exports.NLP = exports.Math = void 0;
36
+ exports.Sort = exports.Search = exports.NLP = exports.Math = exports.Aggregation = void 0;
37
+ exports.Aggregation = __importStar(require("./Aggregation"));
37
38
  exports.Math = __importStar(require("./Math"));
38
39
  exports.NLP = __importStar(require("./NLP"));
39
40
  exports.Search = __importStar(require("./Search"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gabrielrufino/cerebrum",
3
- "version": "2.0.7",
3
+ "version": "2.1.1",
4
4
  "description": "Algorithms made in TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -16,14 +16,14 @@
16
16
  "author": "Gabriel Rufino <contato@gabrielrufino.com>",
17
17
  "license": "UNLICENSED",
18
18
  "devDependencies": {
19
- "@antfu/eslint-config": "^4.14.1",
19
+ "@antfu/eslint-config": "^4.19.0",
20
20
  "@commitlint/cli": "^19.8.1",
21
21
  "@commitlint/config-conventional": "^19.8.1",
22
22
  "@faker-js/faker": "^8.4.1",
23
- "@vitest/coverage-v8": "^3.2.3",
24
- "eslint": "^9.29.0",
23
+ "@vitest/coverage-v8": "^3.2.4",
24
+ "eslint": "^9.32.0",
25
25
  "husky": "^9.1.7",
26
- "typescript": "^5.8.3",
26
+ "typescript": "^5.9.2",
27
27
  "vitest": "^3.0.5"
28
28
  },
29
29
  "funding": [
@@ -0,0 +1,129 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { GroupBy } from './GroupBy'
3
+
4
+ describe('groupBy', () => {
5
+ interface Person {
6
+ name: string
7
+ age: number
8
+ department: string
9
+ salary: number
10
+ }
11
+
12
+ const people: Person[] = [
13
+ { name: 'Alice', age: 30, department: 'Engineering', salary: 100000 },
14
+ { name: 'Bob', age: 25, department: 'Engineering', salary: 80000 },
15
+ { name: 'Charlie', age: 35, department: 'Marketing', salary: 70000 },
16
+ { name: 'Diana', age: 28, department: 'Marketing', salary: 75000 },
17
+ { name: 'Eve', age: 32, department: 'Engineering', salary: 90000 },
18
+ { name: 'Frank', age: 40, department: 'Sales', salary: 85000 },
19
+ ]
20
+
21
+ it('should group items by department', () => {
22
+ const groupBy = new GroupBy(people, 'department')
23
+ const result = groupBy.execute()
24
+
25
+ expect(result).toHaveProperty('Engineering')
26
+ expect(result).toHaveProperty('Marketing')
27
+ expect(result).toHaveProperty('Sales')
28
+
29
+ // eslint-disable-next-line dot-notation
30
+ expect(result['Engineering']).toHaveLength(3)
31
+ // eslint-disable-next-line dot-notation
32
+ expect(result['Marketing']).toHaveLength(2)
33
+ // eslint-disable-next-line dot-notation
34
+ expect(result['Sales']).toHaveLength(1)
35
+
36
+ // eslint-disable-next-line dot-notation
37
+ expect(result['Engineering']).toEqual([
38
+ { name: 'Alice', age: 30, department: 'Engineering', salary: 100000 },
39
+ { name: 'Bob', age: 25, department: 'Engineering', salary: 80000 },
40
+ { name: 'Eve', age: 32, department: 'Engineering', salary: 90000 },
41
+ ])
42
+ })
43
+
44
+ it('should group items by age', () => {
45
+ const groupBy = new GroupBy(people, 'age')
46
+ const result = groupBy.execute()
47
+
48
+ expect(result).toHaveProperty('30')
49
+ expect(result).toHaveProperty('25')
50
+ expect(result).toHaveProperty('35')
51
+ expect(result).toHaveProperty('28')
52
+ expect(result).toHaveProperty('32')
53
+ expect(result).toHaveProperty('40')
54
+
55
+ expect(result['30']).toHaveLength(1)
56
+ expect(result['25']).toHaveLength(1)
57
+ expect(result['30'][0]).toEqual({ name: 'Alice', age: 30, department: 'Engineering', salary: 100000 })
58
+ })
59
+
60
+ it('should handle empty array', () => {
61
+ const groupBy = new GroupBy([], 'department')
62
+ const result = groupBy.execute()
63
+
64
+ expect(result).toEqual({})
65
+ })
66
+
67
+ it('should handle single item', () => {
68
+ const singlePerson = [{ name: 'John', age: 30, department: 'IT', salary: 50000 }]
69
+ const groupBy = new GroupBy(singlePerson, 'department')
70
+ const result = groupBy.execute()
71
+
72
+ expect(result).toHaveProperty('IT')
73
+ // eslint-disable-next-line dot-notation
74
+ expect(result['IT']).toHaveLength(1)
75
+ // eslint-disable-next-line dot-notation
76
+ expect(result['IT'][0]).toEqual({ name: 'John', age: 30, department: 'IT', salary: 50000 })
77
+ })
78
+
79
+ it('should handle all items having same group key', () => {
80
+ const sameDepartment = [
81
+ { name: 'Alice', age: 30, department: 'Engineering', salary: 100000 },
82
+ { name: 'Bob', age: 25, department: 'Engineering', salary: 80000 },
83
+ { name: 'Charlie', age: 35, department: 'Engineering', salary: 70000 },
84
+ ]
85
+
86
+ const groupBy = new GroupBy(sameDepartment, 'department')
87
+ const result = groupBy.execute()
88
+
89
+ expect(result).toHaveProperty('Engineering')
90
+ // eslint-disable-next-line dot-notation
91
+ expect(result['Engineering']).toHaveLength(3)
92
+ expect(Object.keys(result)).toHaveLength(1)
93
+ })
94
+
95
+ it('should work with different data types', () => {
96
+ interface Product {
97
+ id: number
98
+ name: string
99
+ category: string
100
+ inStock: boolean
101
+ }
102
+
103
+ const products: Product[] = [
104
+ { id: 1, name: 'Laptop', category: 'Electronics', inStock: true },
105
+ { id: 2, name: 'Book', category: 'Education', inStock: false },
106
+ { id: 3, name: 'Mouse', category: 'Electronics', inStock: true },
107
+ { id: 4, name: 'Pen', category: 'Education', inStock: true },
108
+ ]
109
+
110
+ const groupBy = new GroupBy(products, 'inStock')
111
+ const result = groupBy.execute()
112
+
113
+ expect(result).toHaveProperty('true')
114
+ expect(result).toHaveProperty('false')
115
+ // eslint-disable-next-line dot-notation
116
+ expect(result['true']).toHaveLength(3)
117
+ // eslint-disable-next-line dot-notation
118
+ expect(result['false']).toHaveLength(1)
119
+ })
120
+
121
+ it('should preserve original object references', () => {
122
+ const originalPerson = people[0]
123
+ const groupBy = new GroupBy(people, 'department')
124
+ const result = groupBy.execute()
125
+
126
+ // eslint-disable-next-line dot-notation
127
+ expect(result['Engineering'][0]).toBe(originalPerson)
128
+ })
129
+ })
@@ -0,0 +1,17 @@
1
+ export class GroupBy<T extends Record<string, any>> {
2
+ constructor(
3
+ private readonly items: Array<T>,
4
+ private readonly key: keyof T,
5
+ ) {}
6
+
7
+ public execute(): Record<string, Array<T>> {
8
+ return this.items.reduce((accumulator, item) => {
9
+ const group = item[this.key]
10
+ if (!accumulator[group]) {
11
+ accumulator[group] = []
12
+ }
13
+ accumulator[group].push(item)
14
+ return accumulator
15
+ }, {} as Record<string, Array<T>>)
16
+ }
17
+ }
@@ -0,0 +1 @@
1
+ export * from './GroupBy'
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * as Aggregation from './Aggregation'
1
2
  export * as Math from './Math'
2
3
  export * as NLP from './NLP'
3
4
  export * as Search from './Search'