有时候,向客户收费时,会创建重复的交易。我们需要找到那些交易,以便可以对其进行处理。交易的所有内容均应相同,但交易ID和发生的时间除外,因为可能会延迟一分钟。
我需要查找所有具有相同sourceAccount,targetAccount,类别,金额的交易,并且每笔连续交易之间的时间差小于1分钟。
我一直在尝试循环数组并使用map创建一个新数组,但是我不知道如何在不提供值引用的情况下匹配该数组,因为该数组中的值是动态的,我可以不知道值。
var transac = [
{
id: 3,
sourceAccount: 'A',
targetAccount: 'B',
amount: 100,
category: 'eating_out',
time: '2018-03-02T10:34:30.000Z'
},
{
id: 1,
sourceAccount: 'A',
targetAccount: 'B',
amount: 100,
category: 'eating_out',
time: '2018-03-02T10:33:00.000Z'
},
{
id: 6,
sourceAccount: 'A',
targetAccount: 'C',
amount: 250,
category: 'other',
time: '2018-03-02T10:33:05.000Z'
},
{
id: 4,
sourceAccount: 'A',
targetAccount: 'B',
amount: 100,
category: 'eating_out',
time: '2018-03-02T10:36:00.000Z'
},
{
id: 2,
sourceAccount: 'A',
targetAccount: 'B',
amount: 100,
category: 'eating_out',
time: '2018-03-02T10:33:50.000Z'
},
{
id: 5,
sourceAccount: 'A',
targetAccount: 'C',
amount: 250,
category: 'other',
time: '2018-03-02T10:33:00.000Z'
}
];
预期:
[
[
{
id: 1,
sourceAccount: "A",
targetAccount: "B",
amount: 100,
category: "eating_out",
time: "2018-03-02T10:33:00.000Z"
},
{
id: 2,
sourceAccount: "A",
targetAccount: "B",
amount: 100,
category: "eating_out",
time: "2018-03-02T10:33:50.000Z"
},
{
id: 3,
sourceAccount: "A",
targetAccount: "B",
amount: 100,
category: "eating_out",
time: "2018-03-02T10:34:30.000Z"
}
],
[
{
id: 5,
sourceAccount: "A",
targetAccount: "C",
amount: 250,
category: "other",
time: "2018-03-02T10:33:00.000Z"
},
{
id: 6,
sourceAccount: "A",
targetAccount: "C",
amount: 250,
category: "other",
time: "2018-03-02T10:33:05.000Z"
}
]
];
答案 0 :(得分:5)
我将为键字段创建一个组合键,并将时间转换为毫秒数,然后按这两个元素进行排序。在第二步组中,具有相同密钥且相距最多1分钟的条目:
"mywork"
在下面的评论后面,上述结果包括所有交易。具有“重复项”的重复项(根据问题中的定义)将其重复项分组在子数组中;那些没有此类重复项的变量将单独出现在其自己的子数组中。
因此,仅获取重复项,请添加适当的过滤器:
WorkManager workManager = WorkManager.getInstance();
ListenableFuture<List<WorkInfo>> workInfos = workManager.getWorkInfosByTag("mywork");
try {
List<WorkInfo> workInfoList = workInfos.get();
for (WorkInfo workInfo : workInfoList) {
WorkInfo.State state = workInfo.getState();
if (state == WorkInfo.State.ENQUEUED) {
UUID workerId = workInfo.getId();
Log.d(TAG, "found enqueued work with id " + workerId);
// BUT HOW DO I TELL WHAT TIME THIS WORK IS SCHEDULED TO RUN?
}
}
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
答案 1 :(得分:1)
解决方案1 解决方案1 天真的方法-数据按日期排序,所有重复项一个接一个。
var first = reducedTransac.shift();
if (!first) {
return [];
}
var reducedTransac = transac.reduce(function(approvedTransac, currentTrans) {
var lastTrans = approvedTransac[approvedTransac.length - 1];
//You'll need to write timeDiff yourself :-)
var isTimeDiffLessThanSecond = timeDiff(lastTrans.date, currentTrans.time) >= 1;
// Also, this can be done in many other ways, I've taken the check out of the if for code clarity, if performance is important move them inside the if...
var isSameSourceAccount = lastTrans.sourceAccount === currentTrans.sourceAccount;
var isSameTargetAccount = lastTrans.targetAccount === currentTrans.targetAccount;
var isSameCategory = lastTrans.category === currentTrans.category;
var isSameAmount = lastTrans.amount === currentTrans.amount;
if (isTimeDiffLessThanSecond && isSameSourceAccount && isSameTargetAccount && isSameCategory && isSameAmount) {
return approvedTransac;
}
approvedTransac.push(currentTrans);
return approvedTransac;
}, [first]);
解决方案2 不了解输入顺序
var first = reducedTransac.shift();
if(!first) {
return [];
}
var transacByTimeGroupedBy = transac.reduce(function(transGroupedByTime, currentTrans) {
var lastTransTimeGB = approvedTransac[approvedTransac.length - 1];
var lastTrans = lastTransTimeGB[lastTransTimeGB.length - 1];
//You'll need to write timeDiff yourself :-)
var isTimeDiffLessThanSecond = timeDiff(lastTrans.date, currentTrans.time) >= 1;
if(isTimeDiffLessThanSecond) {
approvedTransac[approvedTransac.length - 1].push(lastTrans);
} else {
approvedTransac.concat([lastTrans])
}
return approvedTransac;
}, [[first]]);
transacByTimeGroupedBy.map(function(transactions){
var first = transactions.shift();
if(!first) {
return [];
}
return transactions.reduce(function(approvedTransac, currentTrans) {
var lastTrans = approvedTransac[approvedTransac.length - 1];
var isSameSourceAccount = lastTrans.sourceAccount === currentTrans.sourceAccount;
var isSameTargetAccount = lastTrans.targetAccount === currentTrans.targetAccount;
var isSameCategory = lastTrans.category === currentTrans.category;
var isSameAmount = lastTrans.amount === currentTrans.amount;
if(isSameSourceAccount && isSameTargetAccount && isSameCategory && isSameAmount) {
return approvedTransac;
}
approvedTransac.push(currentTrans);
return approvedTransac;
}, [first]);
})
然后,您只需要展平最后一个数组。
未经测试的代码应非常接近您的需求。
答案 2 :(得分:1)
您可以使用以下内容:
var found=false, output=[], transac = [ { id: 3, sourceAccount: 'A', targetAccount: 'B', amount: 100, category: 'eating_out', time: '2018-03-02T10:34:30.000Z' }, { id: 1, sourceAccount: 'A', targetAccount: 'B', amount: 100, category: 'eating_out', time: '2018-03-02T10:33:00.000Z' }, { id: 6, sourceAccount: 'A', targetAccount: 'C', amount: 250, category: 'other', time: '2018-03-02T10:33:05.000Z' }, { id: 4, sourceAccount: 'A', targetAccount: 'B', amount: 100, category: 'eating_out', time: '2018-03-02T10:36:00.000Z' }, { id: 2, sourceAccount: 'A', targetAccount: 'B', amount: 100, category: 'eating_out', time: '2018-03-02T10:33:50.000Z' }, { id: 5, sourceAccount: 'A', targetAccount: 'C', amount: 250, category: 'other', time: '2018-03-02T10:33:00.000Z' } ];
for(i=0;i<transac.length;i++){
j_for:for(j=0;j<output.length;j++){
for(k=0;k<output[j].length;k++){
if(transac[i].sourceAccount==output[j][k].sourceAccount&&transac[i].targetAccount==output[j][k].targetAccount&&transac[i].category==output[j][k].category&&transac[i].amount==output[j][k].amount&&new Date(transac[i].time).getTime()+60000>new Date(output[j][k].time).getTime()&&new Date(transac[i].time).getTime()-60000<new Date(output[j][k].time).getTime()){output[j].push(transac[i]);found=true;break j_for}
}
}
if(!found){output.push([transac[i]])}
found=false
}
console.log(output)
我希望这会对您有所帮助!