I recently tripped across the need to take a list of objects (instances of a class--not sobjects) and split them into smaller lists of 200 members each.
The unit test below shows the code inside a unit test. It passes, but it's not really what I want.
I would like the signature for the method to be:
list<list<object>> listSplit(list<object> aList, integer size)
but the problem with that is a runtime conversion error:
System.TypeException: Invalid conversion from runtime type
List<List<ANY>>
toList<List<String>>
@isTest
public class TomTest
{
// this unit test creates a list of 26 members
// then calls listSplit to create chunks of
// 7 members each, except for the last which
// has the left-overs.
static testMethod void splitTest() {
list<string> alphabet = new list<string> {
'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z'
};
list<list<string>> octaves = listSplit(alphabet, 7);
// I should have my list of lists and the
// first three should have 7 letters each,
// and the last one only 5.
system.assertEquals(4, octaves.size());
system.assertEquals(7, octaves[0].size());
system.assertEquals(7, octaves[1].size());
system.assertEquals(7, octaves[2].size());
system.assertEquals(5, octaves[3].size());
}
// here's the utility for splitting a list into
// smaller parts, but rather than hard-coding the list type,
// I would prefer something generic like list<list<object>>,
// and though the method works fine that way, I can't
// cast the result back to list<list<string>> without throwing
// a runtime conversion exception.
static list<list<string>> listSplit(list<string> aList, integer size)
{
list<list<string>> collector = new list<list<string>>();
integer i = 1;
list<string> petiteList = new list<string>();
for (string each : aList) {
petiteList.add(each);
if (Math.Mod(i, size) == 0) {
collector.add(petiteList);
petiteList = new list<string>();
}
i++;
}
if (petiteList.isEmpty() == false)
collector.add(petiteList);
return collector;
}
}