in a NodeJS service I have an array with objects that have these properties:
This array stores all transactions of different types of batches.
Basically what I need is to be able to get N items from the array, but respecting certain rules:
This is an example of the array:
let batchTransactionsArray = [
{ batchType: 'type1', batchId: '123', transactionId: 'ffasf23' },
{ batchType: 'type1', batchId: '312', transactionId: '423' },
{ batchType: 'type1', batchId: '123', transactionId: '534' },
{ batchType: 'type1', batchId: '312', transactionId: '86' },
{ batchType: 'type2', batchId: '111', transactionId: '97' },
{ batchType: 'type1', batchId: '312', transactionId: '1945' },
{ batchType: 'type1', batchId: '123', transactionId: '79' },
{ batchType: 'type1', batchId: '312', transactionId: '79' },
{ batchType: 'type3', batchId: '425', transactionId: '1555645' },
{ batchType: 'type1', batchId: '123', transactionId: 'fg5' },
{ batchType: 'type1', batchId: '123', transactionId: 'jkh5' },
{ batchType: 'type1', batchId: '312', transactionId: '53j' },
{ batchType: 'type1', batchId: '111', transactionId: '4545' },
{ batchType: 'type2', batchId: '111', transactionId: '534l' },
{ batchType: 'type1', batchId: '111', transactionId: 'jkg435' },
{ batchType: 'type1', batchId: '111', transactionId: 'gfxg23' },
{ batchType: 'type1', batchId: '111', transactionId: '7asdt' },
{ batchType: 'type1', batchId: '222', transactionId: 'jdsa7' },
{ batchType: 'type3', batchId: '663', transactionId: '12423445' },
{ batchType: 'type1', batchId: '111', transactionId: '89saf6' },
{ batchType: 'type1', batchId: '111', transactionId: '12h3g' },
{ batchType: 'type1', batchId: '111', transactionId: '4h3k2hj' },
{ batchType: 'type3', batchId: '663', transactionId: '145' }
];
And an example of the output I need is (if I want 5 transactions from the array):
[{ batchType: 'type1', batchId: '123', transactionId: '534' },
{ batchType: 'type1', batchId: '312', transactionId: '86' },
{ batchType: 'type2', batchId: '111', transactionId: '97' },
{ batchType: 'type2', batchId: '111', transactionId: '534l' },
{ batchType: 'type3', batchId: '663', transactionId: '145' }
]
The criteria for sorting transactionIds would be random, there is no specific order to meet.
I was trying some lodash functions like groupBy and sortBy but no luck yet.
Here is a jsfiddle were I was playing with this: https://jsfiddle.net/20jh3ze7/
I really appreciate suggestions.
You can do this in steps:
To check for uniqueness, you can use a Set
. Since you said you're using lodash, you can use _.groupBy
to group your array by batchItem
and batchId
to get unique elements from each group.
let batchTransactionsArray = [
{ batchType: 'type1', batchId: '123', transactionId: 'ffasf23' },
{ batchType: 'type1', batchId: '312', transactionId: '423' },
{ batchType: 'type1', batchId: '123', transactionId: '534' },
{ batchType: 'type1', batchId: '312', transactionId: '86' },
{ batchType: 'type2', batchId: '111', transactionId: '97' },
{ batchType: 'type1', batchId: '312', transactionId: '1945' },
{ batchType: 'type1', batchId: '123', transactionId: '79' },
{ batchType: 'type1', batchId: '312', transactionId: '79' },
{ batchType: 'type3', batchId: '425', transactionId: '1555645' },
{ batchType: 'type1', batchId: '123', transactionId: 'fg5' },
{ batchType: 'type1', batchId: '123', transactionId: 'jkh5' },
{ batchType: 'type1', batchId: '312', transactionId: '53j' },
{ batchType: 'type1', batchId: '111', transactionId: '4545' },
{ batchType: 'type2', batchId: '111', transactionId: '534l' },
{ batchType: 'type1', batchId: '111', transactionId: 'jkg435' },
{ batchType: 'type1', batchId: '111', transactionId: 'gfxg23' },
{ batchType: 'type1', batchId: '111', transactionId: '7asdt' },
{ batchType: 'type1', batchId: '222', transactionId: 'jdsa7' },
{ batchType: 'type3', batchId: '663', transactionId: '12423445' },
{ batchType: 'type1', batchId: '111', transactionId: '89saf6' },
{ batchType: 'type1', batchId: '111', transactionId: '12h3g' },
{ batchType: 'type1', batchId: '111', transactionId: '4h3k2hj' },
{ batchType: 'type3', batchId: '663', transactionId: '145' }
];
function getNItems(array, N = 5) {
if (N >= array.length) return array;
let batchTypeGroups = _.groupBy(array, e => e.batchType),
res = new Set(), batchIds = new Set();
// add unique batchTypes
for (let [batchType, elements] of Object.entries(batchTypeGroups)) {
if (res.size === N) break;
let d = elements.find(e => !batchIds.has(e.batchId));
if (d) {
res.add(d);
batchIds.add(d.batchId);
} else {
res.add(elements[0]);
}
}
// add remaining unique batchIds
let batchIdGroups = _.groupBy(array.filter(e => !batchIds.has(e.batchId)), e => e.batchId);
for (let [batchId, elements] of Object.entries(batchIdGroups)) {
if (res.size === N) break;
res.add(elements[0]);
}
// add any remaining elements until we have N elements
for (let e of array) {
if (res.size === N) break;
res.add(e);
}
return Array.from(res);
}
console.log(getNItems(batchTransactionsArray, 5));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>