在NodeJS服务中,我有一个数组,其中包含具有以下属性的对象:
此数组存储所有不同类型批次的交易。
基本上,我需要从数组中获取N个项目,但要遵守某些规则:
这是数组的示例:
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' }
];
我需要的输出示例是(如果我要从数组中进行5个事务):
[{ 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' }
]
对transactionIds进行排序的标准是随机的,没有特定的顺序可以满足。
我正在尝试一些lodash函数,例如groupBy和sortBy,但是还没有运气。
这是我正在玩的一个jsfiddle:https://jsfiddle.net/20jh3ze7/
我非常感谢您的建议。
答案 0 :(得分:1)
您可以使用lodash做类似的事情:
let data = [ { 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' } ];
const customTake = (d, n) => {
const roundRobinUnion = (arr) => {
let res = []
while (_.flatten(arr).length)
_.each(arr, x => x.length ? res.push(_.remove(x, (y, i) => i == 0)) : null)
return _.flatten(res)
}
const groups = _(d)
.orderBy(['batchType', 'batchId'])
.groupBy('batchType')
.mapValues(x => _.values(_.groupBy(x, 'batchId')))
.map(x => roundRobinUnion(x))
.value()
return _.take(roundRobinUnion(groups), n)
}
console.log(customTake(data, 3))
console.log(customTake(data, 5))
console.log(customTake(data, 6))
console.log(customTake(data, 8))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
这个想法是将batchType
和batchId
归为一组,并将此问题视为循环联盟。您将遍历每个数组索引,并对每个元素进行并集。
如果您关心排序的最后顺序,您总是可以在结尾处再做一个orderBy
,等等。
这是roundRobinUnion
想法的简单示例:
const data = [
[1, 2, 3],
[1],
[5, 6]
]
const roundRobinUnion = (arr) => {
let res = []
while (_.flatten(arr).length)
_.each(arr, x => x.length ? res.push(_.remove(x, (y, i) => i == 0)) : null)
return _.flatten(res)
}
console.log(roundRobinUnion(data)) // [1,1,5,2,6,3]
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
答案 1 :(得分:0)
您可以按以下步骤进行操作:
要检查唯一性,可以使用Set
。由于您说的是使用lodash,因此可以使用_.groupBy
将数组按batchItem
和batchId
进行分组,以从每个组中获取唯一元素。
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>
答案 2 :(得分:0)
我认为对于这种类型的问题,我们不需要额外的依赖关系。
我们可以使用普通的javascript:)
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" }
];
const getUniqueBatches = () => {
const uniqueBatches = [];
batchTransactionsArray.forEach(b => {
const batchByType = uniqueBatches.find(findBatchByType(b.batchType));
const batchById = uniqueBatches.find(findBatchByBatchId(b.batchId));
if (!batchByType || !batchById) {
uniqueBatches.push(b);
}
});
return uniqueBatches;
};
const findBatchByType = batchType => {
return batch => {
return batch.batchType === batchType;
};
};
const findBatchByBatchId = batchId => {
return batch => {
return batch.batchId === batchId;
};
};
console.log(getUniqueBatches());