javascript - 基于重复键过滤对象数组

标签 javascript arrays node.js

有时,当向客户收费时,会创建重复的交易。我们需要找到这些交易,以便处理它们。关于交易的所有内容都应该相同,除了交易 ID 和交易发生的时间,因为最多可能会有一分钟的延迟。

我需要找出所有具有相同sourceAccount、targetAccount、类别、金额的交易,并且每笔连续交易之间的时间差小于1分钟。

我一直在尝试循环数组并使用 map 创建一个新数组,但我不知道如何在不提供值引用的情况下匹配数组,因为数组中的值是动态的我可以'不知道值(value)。

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"
    }
  ]
];

最佳答案

我会为关键字段创建一个组合键,并将时间转换为毫秒数,然后按这两个元素进行排序。在第二步中,将具有相同 key 且最多相隔 1 分钟的条目分组:

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'}];

const result = transac.map(t => ({
    key: JSON.stringify([t.sourceAccount, t.targetAccount, t.amount, t.category]), 
    epoch: Date.parse(t.time), 
    t
})).sort((a,b) => 
    a.key.localeCompare(b.key) || a.epoch - b.epoch || a.t.id - b.t.id
).reduce(([acc, prev], curr) => {
    if (!prev || curr.key != prev.key || curr.epoch - prev.epoch > 60000) acc.push([]);
    acc[acc.length-1].push(curr.t);
    return [acc, curr];
}, [[]])[0];

console.log(result);

根据下面的评论,上述结果包括所有 交易。具有“重复项”的那些(根据问题中的定义)与子数组中的重复项一起分组;那些没有此类重复项的那些单独出现在它们自己的子数组中。

因此,为了仅获取重复项,请添加适当的过滤器:

const duplicates = result.filter(a => a.length > 1);

关于javascript - 基于重复键过滤对象数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54280260/

相关文章:

c# - 从静态函数调用非静态函数

javascript - 奇怪的 Javascript 数组同步技巧?

javascript - 另一个 "can' t 在发送后设置 header ”

node.js - 如何使用npm安装本地网络中的所有 Node 模块?

node.js - 将express与需要数据的第二个div一起使用的正确方法是什么

javascript - 使用对象的方法设置对象的属性值

javascript - Highcharts - 如何通过 js 切换数据标签?

java - 如何将充满标记的 Object[] 转换为整数数组?

python - 如何打印特定的json列表项?

javascript - Angular Js 范围。$apply 不起作用