Skip to content

Instantly share code, notes, and snippets.

@erkobridee
Last active July 17, 2025 11:00
Show Gist options
  • Save erkobridee/93d6fcbb6b978612b19a5a21d6432768 to your computer and use it in GitHub Desktop.
Save erkobridee/93d6fcbb6b978612b19a5a21d6432768 to your computer and use it in GitHub Desktop.
/*
use case of how to merge 2 similat objects arrays into a new object array
combining the data from them
*/
const ConsumptionType = {
TYPE_1: 'TYPE_1_VALUE',
TYPE_2: 'TYPE_2_VALUE'
} as const satisfies Record<string, string>
type TConsumptionTypeKeys = keyof typeof ConsumptionType;
type TConsumptionType = typeof ConsumptionType[TConsumptionTypeKeys];
interface ITimeRef {
startedAt: string;
endedAt: string;
}
interface IConsumption extends ITimeRef {
amount: number;
type: TConsumptionType;
}
type TCombinedAmountEntry = [TConsumptionType, number];
interface IConsumptionMerged extends ITimeRef {
amounts: TCombinedAmountEntry[];
}
//---------------------------------------------------------------------//
// @begin: merging logic
const mergeAndCombineConsumptions = (...args: IConsumption[][]) => {
const combinedMap = new Map<string, IConsumptionMerged>()
args.forEach(consumptions => {
consumptions.forEach(consumption => {
const { startedAt, endedAt, amount, type } = consumption;
if(!combinedMap.has(startedAt)) {
combinedMap.set(startedAt, {
startedAt,
endedAt,
amounts: [
[type, amount]
]
});
} else {
const combinedConsumption = combinedMap.get(startedAt)!;
combinedConsumption.amounts.push([type, amount]);
}
})
})
return Array.from(combinedMap.values());
}
// @end: merging logic
//---------------------------------------------------------------------//
// @begin: mocked data
const consumptions1: IConsumption[] = [
{ startedAt: '20240101', endedAt: '20240201', amount: 2, type: ConsumptionType.TYPE_1 },
{ startedAt: '20240201', endedAt: '20240301', amount: 1.1, type: ConsumptionType.TYPE_1 }
];
const consumptions2: IConsumption[] = [
{ startedAt: '20240201', endedAt: '20240301', amount: 1.2, type: ConsumptionType.TYPE_2 },
{ startedAt: '20240301', endedAt: '20240401', amount: 2, type: ConsumptionType.TYPE_2 }
];
// @end: mocked data
//---------------------------------------------------------------------//
console.log(
mergeAndCombineConsumptions(
consumptions1,
consumptions2
)
);
/* output:
[{
"startedAt": "20240101",
"endedAt": "20240201",
"amounts": [
[
"TYPE_1_VALUE",
2
]
]
}, {
"startedAt": "20240201",
"endedAt": "20240301",
"amounts": [
[
"TYPE_1_VALUE",
1.1
],
[
"TYPE_2_VALUE",
1.2
]
]
}, {
"startedAt": "20240301",
"endedAt": "20240401",
"amounts": [
[
"TYPE_2_VALUE",
2
]
]
}]
*/
// TypeScript Playground
// https://www.typescriptlang.org/play/?#code/PQKgUABFEK4M4FMIGMCGiIHsBmEAWmA7hAC6YQC2CATgOZIBMEcAlhSwDaolYBGAVgmQk4EVNWqoAnqJYA7MmIhyExTAKE9xkqZGjJMFXvPm1SeJABNuqCNmqHzCCmBDAwYA3Lg8Awpm8YCgAHEhYAgBUpYKQAXggAbz0oCIBNAAUAUQB9AEYALggAcjSsvOyANQBBABkAVUyigBpkiFKchkKSjI7K2oaisABfMVEvH2ZuFjhsFgRRACUhTGpLAB4falMm5hItuVoAPg8SaKQI-0CQsMizgGkEGQh4gGtHnFIzj8u4INDwuRRGIAbjApxibR+fxugLOz0+MW+AV+1wBQIQAG0LsjoWj7o84ABdUFgeQkGjYVDIJAASQibAQS1wSWgu3E5MsVRIhU2plBrIQcksCE53N2+1ooKGHjJFKptKhqICEAQAA9yULRHSGUzEq1UBRMDAFIU5EFeDR+dBwQhCtirv9biDhic4dijPIRVVDcaSJkFNQpPCsYrHbCYjszUYaMSZQo5dSIDTQzCALI0eiWFXqwWWLX0qi6lnQA1GhRwO3+D0qTk+hT+vZSDGx6VgYDAAC0Xe7Pd7ff7A8HQ+H3fbbeAEAAAhbaPJClQ6KYIBxMLPkB5xjwF-QqkKq8YVCmAaJ4gAKAB0l-EtArSaPAWbzYAlM9DnrWZuUIYDyLU6hgvCKjEH+wQbHs2x3jiSpyOmdAiocp5Ph4rLXnA57YCsmRUngp7jLiyKvu+rL6FBYZoRh1BYcgOF4dBhHFsRxGfgkbLUByXI7LmXokDspa+jsNoQCM8S0WGVqMayLDYKeACEBjVr+-7nng6Cnj47LcU+L4MRJjHyT+lggeeiAkGpJAaaKOw6bpunqWx3EtDZTkqkKDmtM5xF8eWhQYu5HkSRiNq8XWJCEn5-kQGFEVQEMT7iTZIwIBwGDWc5n76Z6lj3nI8IZTWRn0KZdnsSQT4yfFHl5SK2Xnl5IjnsE8A4YFZzBWWoVxeFxHSrpsWtH1rTUAgJAwNQOVVBI0joQ4FC4d+mVGQAbqgHAwPMiGda27ZTrm84ZkuK5ruOI4nadZ1nWO23Tggs5yPOmDIG8WbWOZG7IjwokwnABSQQ6MLNsGrQscV3FdAwAAMDAACzg7ksPNC5wqimDkMwxDuQI3VhQMAJZyFNl6Lnu0eRCY50DA+Z9nI8UEPQ5D8Oca51NFLTMMAMwM2IIWFLk565LjMT46RMKE8TuRCWAsaeO9X5-cenS-SiYYA-EvmshTFlcijdPowjXHM6z4McxjbW+jz544witoQATZxEz02RMEMZNQBrVNazTqNG5z+seyzXswybXPtdjAvW7bMT22UTuSySV27ZQD1PRAL2oMd50Z5nGdjtL3iYBwCDnodp6tNuCC7ll82HsLx4l7pn3HvzXUN8iDCtEhcVAA
/*
Method 3: Merging and Combining Properties
source: https://www.spguides.com/typescript-array-concatenation/
*/
interface User {
id: number;
name?: string;
email?: string;
}
const array1: User[] = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob', email: '[email protected]' }
];
const array2: User[] = [
{ id: 3, name: 'Charlie', email: '[email protected]' },
{ id: 4, name: 'David', email: '[email protected]' },
{ id: 1, email: '[email protected]' },
];
const mergeAndCombine = (arr1: User[], arr2: User[]): User[] => {
const combinedMap = new Map<number, User>();
[...arr1, ...arr2].forEach(user => {
if (!combinedMap.has(user.id)) {
combinedMap.set(user.id, user);
} else {
combinedMap.set(user.id, { ...combinedMap.get(user.id), ...user });
}
});
return Array.from(combinedMap.values());
};
const combinedMergedArray = mergeAndCombine(array1, array2);
console.log(combinedMergedArray);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment