I had a scenario where I needed to sort a list of EmailTemplate
, but didn't have anything to sort the list by (other than a common number in the Name
property).
The email templates looked something like this:
Some email template - 1
Some other email template - 2
Another email template - 3 (with end text)
Xylophone email template - 4
Aardvark email template - 5 (with end text)
Here's the code I wrote:
public static List<EmailTemplate> OrderEmailTemplates(List<EmailTemplate> emailTemplates)
{
Integer n = emailTemplates.size();
for(Integer i = 0; i < n; i++)
{
for(Integer j = 0; j < n - i - 1; j++)
{
if(!AreTemplatesInOrder(emailTemplates[j], emailTemplates[j+1]))
{
EmailTemplate temp = emailTemplates[j];
emailTemplates[j] = emailTemplates[j+1];
emailTemplates[j+1] = temp;
}
}
}
return emailTemplates;
}
private static Boolean AreTemplatesInOrder(EmailTemplate t1, EmailTemplate t2)
{
return RetrieveNumberFromTemplateName(t1) < RetrieveNumberFromTemplateName(t2);
}
private static Integer RetrieveNumberFromTemplateName(EmailTemplate template)
{
return Integer.valueOf(template.Name.split('-')[1].replaceAll('[a-zA-Z]{1,}|\\-', '').trim());
}
It feels a little verbose considering the task. Perhaps I'm too used to using mordern manipulation/querying technologies like LINQ.
Is there a less verbose way of doing this in Apex?
Some useful syntax would be something like the following, though I'm sure it doesn't exist (ignoring the lambda, it's there for readability):
emailTemplates.OrderBy((x,y) => AreTemplatesInOrder(x,y));
1 Answer 1
For a less verbose way to achieve this in Apex you need to create a wrapper class for EmailTemplate that implements Comparable interface. The advantage is that elements don't need to be manually moved in the array.
public static EmailTemplate[] orderEmailTemplates(List<EmailTemplate> emailTemplates) {
EmailTemplateWrapper[] wrappers = new List<EmailTemplateWrapper>();
for(EmailTemplate template : emailTemplates) {
wrappers.add(new EmailTemplateWrapper(template));
}
wrappers.sort();
EmailTemplate[] sortedTemplates = new List<EmailTemplate>();
for(EmailTemplateWrapper wrapper : wrappers) {
sortedTemplates.add(wrapper.record);
}
return sortedTemplates;
}
class EmailTemplateWrapper implements Comparable {
public EmailTemplate record { public get; set; }
public EmailTemplateWrapper(EmailTemplate record) {
this.record = record;
}
public Integer compareTo(Object compareTo) {
if(!(compareTo instanceOf EmailTemplateWrapper)) {
return -1;
}
EmailTemplate otherRecord = ((EmailTemplateWrapper) compareTo).record;
Integer numerForThisRecord = retrieveNumberFromTemplateName(record);
Integer numerForOtherRecord = retrieveNumberFromTemplateName(otherRecord);
if(numerForThisRecord == numerForOtherRecord ) {
return 0;
} else if(numerForThisRecord < numerForOtherRecord) {
return -1;
}
return 1;
}
Integer retrieveNumberFromTemplateName(EmailTemplate template){
return Integer.valueOf(template.Name.split('-')[1].replaceAll('[a-zA-Z]{1,}|\\-', '').trim());
}
}
-
1\$\begingroup\$ Welcome to code Review! by "to do so" - is that in response to the OP's question "Is there a less verbose way of doing this in Apex?"? \$\endgroup\$2022年08月04日 17:21:10 +00:00Commented Aug 4, 2022 at 17:21
-
1\$\begingroup\$ Hi! Yes. I believe this answer presents less verbose way of sorting array because you don't have to manually move elements in array. \$\endgroup\$ziemniakoss– ziemniakoss2022年08月04日 17:46:31 +00:00Commented Aug 4, 2022 at 17:46