Reputation: 190
I am trying to get duplicate objects within an array based on 2 properties. Let's say the object is like below.
let arry = [
{Level: "A-1", Status: "approved"},
{Level: "A-2", Status: "approved"},
{Level: "A-3", Status: "approved"},
{Level: "A-4", Status: "reject"},
{Level: "A-5", Status: "reject"},
{Level: "A-1", Status: "approved"},
{Level: "A-2", Status: "approved"},
{Level: "A-6", Status: "approved"},
{Level: "A-7", Status: "reject"},
{Level: "A-1", Status: "approved"},
{Level: "A-6", Status: "approved"},
]
Duplicate objects should return and only the Status "approved" once like below:
[
{Level: "A-1", Status: "approved"},
{Level: "A-2", Status: "approved"}
]
Upvotes: 0
Views: 696
Reputation: 100
let arry = [
{Level: "A-1", Status: "approved"},
{Level: "A-2", Status: "approved"},
{Level: "A-3", Status: "approved"},
{Level: "A-4", Status: "reject"},
{Level: "A-5", Status: "reject"},
{Level: "A-1", Status: "approved"},
{Level: "A-2", Status: "approved"},
{Level: "A-6", Status: "approved"},
{Level: "A-7", Status: "reject"},
{Level: "A-1", Status: "approved"},
{Level: "A-6", Status: "approved"},
]
function dups(arry) {
const hashMap = {};
return arry.reduce((acc, curr) => {
const level = curr.Level;
if(hashMap[level] && hashMap[level] === 1 && curr.Status === 'approved') {
acc.push(curr);
hashMap[level]++;
} else {
hashMap[level] = 1;
}
return acc;
}, []);
}
console.log(dups(arry));
Upvotes: 1
Reputation: 4912
You can use Array.reduce
to keep track of all the previous items as it iterates through the array, while preserving only the ones it's seen before (whose Status
is "approved"
).
In order to not output duplicates of duplicates, it also checks if the current duplicate was already found as a duplicate, and ignores it if so.
const array = [
{ Level: "A-1", Status: "approved" },
{ Level: "A-2", Status: "approved" },
{ Level: "A-3", Status: "approved" },
{ Level: "A-4", Status: "reject" },
{ Level: "A-5", Status: "reject" },
{ Level: "A-1", Status: "approved" },
{ Level: "A-2", Status: "approved" },
{ Level: "A-6", Status: "approved" },
{ Level: "A-7", Status: "reject" },
{ Level: "A-1", Status: "approved" },
{ Level: "A-6", Status: "approved" },
];
const dupes = array.reduce((dupes, { Level, Status }, i) => {
const matches = ({ Level: l, Status: s }) => l == Level && s == Status;
const match = dupes.memory.find(matches);
const found = dupes.dupes.find(matches);
(match?.Status == 'approved' && !found)
? dupes.dupes.push({ Level, Status })
: dupes.memory.push({ Level, Status });
return (i == array.length - 1) ? dupes.dupes : dupes;
}, { dupes: [], memory: [] });
console.log(dupes);
A less general but more terse strategy might be:
const dupes = [...new Set(array
.filter(({ Status: s }) => s == 'approved')
.map(({ Level: l }) => +l.match(/\d+/)[0])
.filter((num, _, arr) => arr.filter((n) => n == num).length > 1))]
.map((n) => ({ Level: 'A-' + n, Status: 'approved' }));
For example:
const array = [
{ Level: "A-1", Status: "approved" },
{ Level: "A-2", Status: "approved" },
{ Level: "A-3", Status: "approved" },
{ Level: "A-4", Status: "reject" },
{ Level: "A-5", Status: "reject" },
{ Level: "A-1", Status: "approved" },
{ Level: "A-2", Status: "approved" },
{ Level: "A-6", Status: "approved" },
{ Level: "A-7", Status: "reject" },
{ Level: "A-1", Status: "approved" },
{ Level: "A-6", Status: "approved" },
];
const dupes = [...new Set(array
.filter(({ Status: s }) => s == 'approved')
.map(({ Level: l }) => +l.match(/\d+/)[0])
.filter((num, _, arr) => arr.filter((n) => n == num).length > 1))]
.map((n) => ({ Level: 'A-' + n, Status: 'approved' }));
console.log(dupes);
Upvotes: 1