1

I have a requirement where I need to find duplicates and remove from the list, but I am unable to figure how to iterate and remove duplicates. Can anyone please help me with this? I don't want to use sets, my requirement is different so I want to process within the list.

 public List<Schedules__c> planSchedule(Map<Id, Opportunity> OppsPriorID) {

        List<Schedules__c> SchedulesToProcess = [
            SELECT Opportunity__c,Month__c,Year__c, term__c
            FROM Schedules__c
            WHERE Opportunity__c IN : OppsPriorID.keySet()
        ];
        
        /*the above list may contain duplicates that means for different records Month__c and Year__c values will be same
        Record 1: Opportunity__c = 'Test',Month__c = 'Aug',Year__c = 2021, term__c = 1
        Record 2: Opportunity__c = 'Test',Month__c = 'Aug',Year__c = 2021, term__c = 2
        Record 3: Opportunity__c = 'Test',Month__c = 'Mar',Year__c = 2021, term__c = 1
        Record 4: Opportunity__c = 'Test',Month__c = 'Sep',Year__c = 2021, term__c = 3
        
        Since Month and Year are repeating,we are considering Record 1 and Record 2 are duplicates even term__c field is different 
        so when iterating list below I would like to remove Record 2*/
        
        
        for (Schedules__c oppSchedule : SchedulesToProcess) {
            oppSchedule.Opportunity__c = OppsPriorID.get(oppSchedule.Opportunity__c).Id;
             
        }
        return SchedulesToProcess;        
    }

2 Answers 2

3

The easiest is to create a Set<Object[]>, something like the following:

Set<Object[]> alreadySeen = new Set<Object[]>();
List<Schedules__c> uniqueSchedules = new List<Schedules__c>();

for (Schedules__c schedules : SchedulesToProcess) {
  Object[] key = new Object[]{ schedules.Month__c,
    schedules.Year__c };

  if (!alreadySeen.contains(key)) {
    uniqueSchedules.add(schedules);
    alreadySeen.add(key);
  }
}

This takes the two important values and uses them as a value that can be added to a set. Object arrays nicely handle equals and hashCode which makes them ideal here.

At the end, the unique entries are in uniqueSchedules.

1
  • 2
    P.S. you can change the if statement to use the return value from add; it returns true when the collection is modified: if (alreadySeen.add(key)) { uniqueSchedules.add(schedules); }
    – sfdcfox
    Commented Apr 5, 2021 at 21:48
0

If you add an ORDER BY clause to your SOQL statement, then you can loop through the list of Schedules and remove the subsequent matching Schedules.

List<Schedules__c> SchedulesToProcess = [
        SELECT Opportunity__c, Month__c, Year__c, term__c
        FROM Schedules__c
        WHERE Opportunity__c IN : OppsPriorID.keySet()
        ORDER BY Month__c,
                Year__c,
                term__c
];

for (Integer index = 0; index < SchedulesToProcess.size();) {
    if (index + 1 != SchedulesToProcess.size() &&
                    SchedulesToProcess.get(index).Month__c == SchedulesToProcess.get(index + 1).Month__c &&
                    SchedulesToProcess.get(index).Year__c == SchedulesToProcess.get(index + 1).Year__c) {
        SchedulesToProcess.remove(index + 1);
    }
    else {
        index++;
    }
}
1
  • A while loop would be cleaner here. Otherwise a reasonable solution assuming ordering can be changed (which I suspect it can be here).
    – Phil W
    Commented Apr 5, 2021 at 21:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .