Find Duplicate Records?

Issue

Find all transactions that have the same sourceAccount, targetAccount, category, amount,
and the time difference between each consecutive transaction is less than 1 minute.

Data Set

[
  {
    "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"
  }
]

List of all the duplicate transaction groups (category), ordered by time ascending.

The groups (category) should be sorted in ascending order of the first transaction in the group.

Expected Output

[
  [
    {
      "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"
    }
  ]
]

Below is the code I tried

let transactions = []
var clean = records.filter((arr, index, self) =>
  index === self.findIndex((t) => (t.sourceAccount === arr.sourceAccount && t.targetAccount === arr.targetAccount && t.category === arr.category && t.amount === arr.amount)))

if(clean.length > 1){
    // array contains duplicate elements.
    transactions.push(clean)
}

return transactions

Output I get from the above code

[
    [
        {
            "id": 3,
            "sourceAccount": "A",
            "targetAccount": "B",
            "amount": 100,
            "category": "eating_out",
            "time": "2018-03-02T10:34:30.000Z"
        },
        {
            "id": 6,
            "sourceAccount": "A",
            "targetAccount": "C",
            "amount": 250,
            "category": "other",
            "time": "2018-03-02T10:33:05.000Z"
        },
        {
            "id": 4,
            "sourceAccount": "Aw",
            "targetAccount": "D",
            "amount": 1002,
            "category": "eating_out2",
            "time": "2018-03-02T10:36:00.000Z"
        }
    ]
]

Try lot of different codes but unable to get the expected output from dataset.
Can someone help me to get the Expected Output?

Solution

Try this:

function findTransactions(input) {
    const checkTimeDiff = (time1, time2) => {
        const diff = Number(new Date(time1)) - Number(new Date(time2))
        return diff < 60 * 1000;
    }
    
    let result= []
    for (let i = 0; i < input.length; i++) {
        let next= []
        let found = false;
        for (let j = i + 1; j < input.length; j++) {
            if (input[j].sourceAccount === input[i].sourceAccount && 
                input[j].targetAccount === input[i].targetAccount && 
                checkTimeDiff(input[j].time, input[i].time) &&
                input[j].category === input[i].category &&
                input[j].amount === input[i].amount) {
                next.push(input[j]) 
                input.splice(j, 1)
                if (!found) {
                    next.push(input[i])
                    found = true;
                }
            }
        }
        if (next.length > 0) result.push(next);
    }

    return result;
}

Answered By – sorold

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published