Skip to content

Commit

Permalink
add includeOtherProperties to transposeObjectArray (#32)
Browse files Browse the repository at this point in the history
* add includeOtherProperties to transposeObjectArray

* execute all tests

* fix lint

* pre-commit
  • Loading branch information
abrantesarthur authored Jan 14, 2025
1 parent 9d00d53 commit d7e23a3
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 28 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"author": "Transcend Inc.",
"name": "@transcend-io/type-utils",
"description": "Small package containing useful typescript utilities.",
"version": "1.8.0",
"version": "1.8.1",
"homepage": "https://github.com/transcend-io/type-utils",
"repository": {
"type": "git",
Expand Down
71 changes: 54 additions & 17 deletions src/tests/transposeObjectArray.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ import { transposeObjectArray } from '../transposeObjectArray';

describe('transposeObjectArray', () => {
it('should handle empty array', () => {
const result = transposeObjectArray([], ['id', 'name']);
const result = transposeObjectArray({
objects: [],
properties: ['id', 'name'],
});
expect(result).to.deep.equal({});
});

it('should extract multiple properties from array of objects', () => {
const items = [
const objects = [
{ id: 1, name: 'John', age: 25, city: 'NY' },
{ id: 2, name: 'Jane', age: 30, city: 'LA' },
];
const result = transposeObjectArray(items, ['id', 'name']);
const result = transposeObjectArray({
objects,
properties: ['id', 'name'],
});
expect(result).to.deep.equal({
id: [1, 2],
name: ['John', 'Jane'],
Expand All @@ -24,12 +30,15 @@ describe('transposeObjectArray', () => {
});

it('should handle objects with missing properties', () => {
const items = [
const objects = [
{ id: 1, name: 'John', age: 25 },
{ id: 2, age: 30 },
{ id: 3, name: 'Bob', city: 'LA' },
];
const result = transposeObjectArray(items, ['id', 'name']);
const result = transposeObjectArray({
objects,
properties: ['id', 'name'],
});
expect(result).to.deep.equal({
id: [1, 2, 3],
name: ['John', undefined, 'Bob'],
Expand All @@ -38,11 +47,14 @@ describe('transposeObjectArray', () => {
});

it('should handle different value types', () => {
const items = [
const objects = [
{ id: 1, active: true, count: 10, tags: ['a', 'b'] },
{ id: 2, active: false, count: 20, tags: ['c'] },
];
const result = transposeObjectArray(items, ['active', 'tags']);
const result = transposeObjectArray({
objects,
properties: ['active', 'tags'],
});
expect(result).to.deep.equal({
active: [true, false],
tags: [['a', 'b'], ['c']],
Expand All @@ -54,11 +66,14 @@ describe('transposeObjectArray', () => {
});

it('should handle extracting all properties (empty rest)', () => {
const items = [
const objects = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
];
const result = transposeObjectArray(items, ['id', 'name']);
const result = transposeObjectArray({
objects,
properties: ['id', 'name'],
});
expect(result).to.deep.equal({
id: [1, 2],
name: ['John', 'Jane'],
Expand All @@ -67,11 +82,11 @@ describe('transposeObjectArray', () => {
});

it('should handle extracting no properties (everything in rest)', () => {
const items = [
const objects = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
];
const result = transposeObjectArray(items, []);
const result = transposeObjectArray({ objects, properties: [] });
expect(result).to.deep.equal({
rest: [
{ id: 1, name: 'John' },
Expand All @@ -81,11 +96,14 @@ describe('transposeObjectArray', () => {
});

it('should handle objects with null or undefined values', () => {
const items = [
const objects = [
{ id: 1, name: null, age: 25 },
{ id: 2, name: undefined, age: 30 },
];
const result = transposeObjectArray(items, ['id', 'name']);
const result = transposeObjectArray({
objects,
properties: ['id', 'name'],
});
expect(result).to.deep.equal({
id: [1, 2],
name: [null, undefined],
Expand All @@ -94,11 +112,14 @@ describe('transposeObjectArray', () => {
});

it('should handle nested objects', () => {
const items = [
const objects = [
{ id: 1, user: { name: 'John', age: 25 } },
{ id: 2, user: { name: 'Jane', age: 30 } },
];
const result = transposeObjectArray(items, ['id', 'user']);
const result = transposeObjectArray({
objects,
properties: ['id', 'user'],
});
expect(result).to.deep.equal({
id: [1, 2],
user: [
Expand All @@ -110,11 +131,11 @@ describe('transposeObjectArray', () => {
});

it('should preserve property order in rest object', () => {
const items = [
const objects = [
{ a: 1, b: 2, c: 3, d: 4 },
{ a: 5, b: 6, c: 7, d: 8 },
];
const result = transposeObjectArray(items, ['a', 'c']);
const result = transposeObjectArray({ objects, properties: ['a', 'c'] });
expect(result).to.deep.equal({
a: [1, 5],
c: [3, 7],
Expand All @@ -124,4 +145,20 @@ describe('transposeObjectArray', () => {
],
});
});

it('should omit rest properties if includeOtherProperties is false', () => {
const objects = [
{ id: 1, name: null, age: 25 },
{ id: 2, name: undefined, age: 30 },
];
const result = transposeObjectArray({
objects,
properties: ['id', 'name'],
options: { includeOtherProperties: false },
});
expect(result).to.deep.equal({
id: [1, 2],
name: [null, undefined],
});
});
});
32 changes: 22 additions & 10 deletions src/transposeObjectArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,36 @@ type TransposedObjectArray<T, K extends keyof T> = {
* while keeping the remaining properties grouped in a 'rest' array.
* @template T - The type of objects in the input array
* @template K - The keys of properties to transpose
* @param items - Array of objects to transpose
* @param properties - Array of property keys to transpose into arrays
* @param param - the objects, properties, and transposing options
* @returns An object containing transposed arrays for each selected property
* @example
* const items = [
* const objects = [
* { id: 1, name: 'John', age: 25 },
* { id: 2, name: 'Jane', age: 30 }
* ]
* const result = transposeObjectArray(items, ['id', 'name']);
* const result = transposeObjectArray({objects, properties: ['id', 'name']});
* // Returns: {
* // id: [1, 2],
* // name: ['John', 'Jane'],
* // rest: [{age: 25}, {age: 30}]
* // }
*/
export const transposeObjectArray = <T extends object, K extends keyof T>(
items: T[],
properties: K[],
): TransposedObjectArray<T, K> =>
items.reduce(
export const transposeObjectArray = <T extends object, K extends keyof T>({
objects,
properties,
options = { includeOtherProperties: true },
}: {
/** Array of objects to transpose */
objects: T[];
/** Array of property keys to transpose into arrays */
properties: K[];
/** Options for how to transpose the array */
options?: {
/** Whether to include non-tranposed properties in the final result */
includeOtherProperties?: boolean;
};
}): TransposedObjectArray<T, K> =>
objects.reduce(
(acc, item) => {
const result = { ...acc } as TransposedObjectArray<T, K>;

Expand All @@ -77,7 +87,9 @@ export const transposeObjectArray = <T extends object, K extends keyof T>(
}
});

result.rest = [...(acc.rest || []), restObject];
if (options.includeOtherProperties) {
result.rest = [...(acc.rest || []), restObject];
}

return result;
},
Expand Down

0 comments on commit d7e23a3

Please sign in to comment.