0

I have a list of 15,000 records. I can maintain the count in a flag.

Integer Counter = 15000;

I want to break my main list into 3 small lists. Each list should contain 5,000 records. First list should contain first 5000 records and second list should contain the next 5,000 records and so on.

The reason behind this: I want to pass each list of 5000 records to a queueable job or create three queueable jobs.

if(mainLst.size() > counter)
{
    List<Custom__C> newList = new List<Custom__C>();
    List<Custom__C> newList1 = new List<Custom__C>();
    List<Custom__C> newList2 = new List<Custom__C>();
    for(Integer i = 0; i< counter; i++)
    {
        newList1.add(mainLst[i]);
    }
    // Perform some operation with newList1    
    // Perform some operation with newList2 
    // Perform some operation with newList3                                   
}  
  • What is the purpose of splitting up this list? It will not allow you to circumvent DML-related limits, for example. Or is this some type of exercise? – David Reed Oct 18 '18 at 11:44
  • I want to pass these three lists to a queuable/batchapex. – Ramy Oct 18 '18 at 19:49
3

well, you can use the following my class that I have written with help of community to split List into parts. To read about main logic of splitting you can check How to write a generic list method that will cast at runtime sfdcfox's answer

public with sharing class Lists {

    public static List<List<Object>> doPartions(List<Object> records, Integer size, Type destType){
        checkNotNull(records);
        checkArgument(size > 0);
        checkNotNull(destType);
        return new Partition(records, size, destType).doPartition();
    }

    private static void checkNotNull(Object reference) {
        if (reference == null) {
            throw new NullPointerException();
        }
    }

    private static void checkArgument(Boolean expression) {
        if (!expression) {
            throw new IllegalArgumentException();
        }
    }

    private class Partition{
        private List<Object> items;
        private Integer splitSize;
        private Type destType;

        Partition(List<Object> records, Integer size, Type destType){
            this.items = records;
            this.splitSize = size;
            this.destType = destType;
        }

        List<List<Object>> doPartition(){
            List<List<Object>> result = (List<List<Object>>)destType.newInstance();
            List<Object> protoList = items.clone();
            protoList.clear();
            List<Object> tempList = protoList.clone();
            Integer index = 0, count = 0, size = items.size();
            while(index < size) {
                tempList.add(items.get(index++));
                ++count;
                if(count == splitSize) {
                    result.add(tempList);
                    tempList = protoList.clone();
                    count = 0;
                }
            }
            if(!tempList.isEmpty()) {
                result.add(tempList);
            }
            return result;
        }
    }

    public class IllegalArgumentException extends Exception {}
}

unit-tests

@isTest
private class ListsTest {

    @isTest
    static void testCorrectPartions(){
        List<Integer> records = new List<Integer> {
            1, 2, 3, 4, 5
            };
        Test.startTest();
            List<List<Integer>> actual = (List<List<Integer>>) Lists.doPartions(records, 2, List<List<Integer>>.class);
        Test.stopTest();
        System.assertEquals(3, actual.size(), 'Incorrect number of partions');
        Integer tempNumber = 1;
        for(List<Integer> itemsActual :actual){
            for(Integer numb :itemsActual){
                System.assertEquals(tempNumber, numb, 'Order of elements isn\'t saved');
                ++tempNumber;
            }
        }
    }
}

Usage in your case

List<List<Custom__c>> partionLists = (List<List<Custom__c>>) Lists.doPartions(mainLst, 5000, List<List<Custom__c>>.class);
2

You can use switch case to your advantage.

if(mainLst.size() > counter)
{
    List<Custom__C> newList = new List<Custom__C>();
    List<Custom__C> newList1 = new List<Custom__C>();
    List<Custom__C> newList2 = new List<Custom__C>();
    for(Integer i = 0; i< counter; i++)
    {
        Switch on Math.mod(counter,3){
            when 0{
                newList.add(mainLst[i]);
            }
            when 1{
                newList1.add(mainLst[i]);
            }
            when 2{
                newList2.add(mainLst[i]);
            }
        }

    }
    // Perform some operation with newList1    
    // Perform some operation with newList2 
    // Perform some operation with newList3                                   
}  

As david mentioned it will still not allow you to more DML than 10K limit. You have to move it in Batch/Future/Queuebale

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.