Skip to content

Commit

Permalink
Merge pull request #29 from PearTree-to/groupBy
Browse files Browse the repository at this point in the history
Group By util
  • Loading branch information
prdn authored Jun 7, 2024
2 parents cea3c99 + 9a823c9 commit 59afc56
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#1.13.0
- feat: groupBy

#1.12.0
- feat: sum
- feat: sumBy
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Currently supported utils:
- `get` - get the object members by path
- `getArrayHasIntersect` - checks if arrays have at least one common value
- `getArrayUniq` - gets unique values form array
- `groupBy` - groups the elements of an array by a specified key.
- `isEmpty` - checks if value is an empty object, collection, map, or set
- `isEqual` - check if passed two values are equal
- `isFinite` - checks if input is a finite number.
Expand Down
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export function freezeDeep (obj: Object): Object
export function get (obj: Object, path: string | Array<string | number>, defaultValue: any): any
export function getArrayHasIntersect (arr1: Array<any>, arr2: Array<any>): boolean
export function getArrayUniq (arr: Array<any>): Array<any>
export function groupBy<T> (array: Array<T>, key: string | ((item: T) => string)): { [key: string]: Array<T> }
export function isEmpty (val: any): boolean
export function isEqual (value: any, another: any): boolean
export function isFinite (val: any): boolean
Expand Down
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const get = require('./src/get')
const getArrayHasIntersect = require('./src/getArrayHasIntersect')
const getArrayUniq = require('./src/getArrayUniq')
const getErrorMessage = require('./src/getErrorMessage')
const groupBy = require('./src/groupBy')
const isEmpty = require('./src/isEmpty')
const isEqual = require('./src/isEqual')
const isFinite = require('./src/isFinite')
Expand Down Expand Up @@ -38,6 +39,7 @@ module.exports = {
getArrayHasIntersect,
getArrayUniq,
getErrorMessage,
groupBy,
isEmpty,
isEqual,
isFinite,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bitfinexcom/lib-js-util-base",
"version": "1.12.0",
"version": "1.13.0",
"description": "general utils",
"main": "index.js",
"scripts": {
Expand Down
21 changes: 21 additions & 0 deletions src/groupBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict'

/**
* Groups the elements of an array by a specified key.
*
* @param {Array} array - The array to group.
* @param {Function|string} key - The key to group by, or a function to determine the group key.
* @returns {Object} An object where keys are group names and values are arrays of grouped items.
*/
const groupBy = (array, key) => {
return array.reduce((result, item) => {
const groupKey = typeof key === 'function' ? key(item) : item[key]
if (!result[groupKey]) {
result[groupKey] = []
}
result[groupKey].push(item)
return result
}, {})
}

module.exports = groupBy
106 changes: 106 additions & 0 deletions test/groupBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use strict'

/* eslint-env mocha */

const assert = require('assert')
const { groupBy } = require('../index')

describe('groupBy', () => {
it('should group items by string property key', () => {
const items = [
{ id: 1, category: 'fiat', name: 'USD' },
{ id: 2, category: 'fiat', name: 'EUR' },
{ id: 3, category: 'crypto', name: 'USDT' },
{ id: 4, category: 'fiat', name: 'INR' },
{ id: 5, category: 'crypto', name: 'EURT' }
]

const groupedItems = groupBy(items, 'category')

assert.deepStrictEqual(groupedItems, {
fiat: [
{ id: 1, category: 'fiat', name: 'USD' },
{ id: 2, category: 'fiat', name: 'EUR' },
{ id: 4, category: 'fiat', name: 'INR' }
],
crypto: [
{ id: 3, category: 'crypto', name: 'USDT' },
{ id: 5, category: 'crypto', name: 'EURT' }
]
})
})

it('should group items by number property key', () => {
const items = [
{ id: 1, balance: 25 },
{ id: 2, balance: 30 },
{ id: 3, balance: 25 },
{ id: 4, balance: 40 }
]

const groupedItems = groupBy(items, 'balance')

assert.deepStrictEqual(groupedItems, {
25: [
{ id: 1, balance: 25 },
{ id: 3, balance: 25 }
],
30: [{ id: 2, balance: 30 }],
40: [{ id: 4, balance: 40 }]
})
})

it('should group items by computed key using a function', () => {
const items = [
{ id: 1, category: 'fiat', name: 'USD' },
{ id: 2, category: 'fiat', name: 'EUR' },
{ id: 3, category: 'crypto', name: 'USDT' },
{ id: 4, category: 'fiat', name: 'INR' },
{ id: 5, category: 'crypto', name: 'EURT' }
]

const groupedItems = groupBy(items, item => item.name.charAt(0))

assert.deepStrictEqual(groupedItems, {
U: [{ id: 1, category: 'fiat', name: 'USD' }, { id: 3, category: 'crypto', name: 'USDT' }],
E: [{ id: 2, category: 'fiat', name: 'EUR' }, { id: 5, category: 'crypto', name: 'EURT' }],
I: [{ id: 4, category: 'fiat', name: 'INR' }]
})
})

it('should group items by function returning a number', () => {
const items = [
{ id: 1, balance: 25 },
{ id: 2, balance: 30 },
{ id: 3, balance: 25 },
{ id: 4, balance: 40 }
]

const groupedItems = groupBy(items, item => Math.floor(item.balance / 10))

assert.deepStrictEqual(groupedItems, {
2: [
{ id: 1, balance: 25 },
{ id: 3, balance: 25 }
],
3: [{ id: 2, balance: 30 }],
4: [{ id: 4, balance: 40 }]
})
})

it('should handle empty array', () => {
const items = []
const groupedItems = groupBy(items, 'category')

assert.deepStrictEqual(groupedItems, {})
})

it('should handle array with one item', () => {
const items = [{ id: 1, category: 'fiat', name: 'USD' }]
const groupedItems = groupBy(items, 'category')

assert.deepStrictEqual(groupedItems, {
fiat: [{ id: 1, category: 'fiat', name: 'USD' }]
})
})
})

0 comments on commit 59afc56

Please sign in to comment.