Skip to content

Instantly share code, notes, and snippets.

@FishOfPrey
Created August 29, 2023 02:25
Show Gist options
  • Select an option

  • Save FishOfPrey/e35bcd2f86ac977f5103f8a6d9f9f5de to your computer and use it in GitHub Desktop.

Select an option

Save FishOfPrey/e35bcd2f86ac977f5103f8a6d9f9f5de to your computer and use it in GitHub Desktop.

Revisions

  1. FishOfPrey created this gist Aug 29, 2023.
    92 changes: 92 additions & 0 deletions sObjectComparator.cls
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,92 @@
    public class sObjectComparator implements Comparator<sObject> {

    // Asc and Desc are reserved keywords in Apex!
    public enum SortOrder { Ascend, Descend}

    private Schema.sObjectField sortField;
    private DescribeFieldResult describeResult;

    public SortOrder order {
    get;
    set {
    order = value;
    }
    }

    public sObjectComparator(Schema.sObjectField compareField) {
    sortField = compareField;
    describeResult = sortField.getDescribe();
    order = SortOrder.Ascend;
    }

    public integer compare(sObject s1, sObject s2) {

    integer compareResult;

    // Handle null objects before null field values
    if(s1 == null && s2 == null) {
    compareResult = 0;
    } else if (s1 == null) {
    compareResult = -1;
    } else if (s2 == null) {
    compareResult = 1;
    } else {
    object s1FieldValue = s1?.get(sortField);
    object s2FieldValue = s2?.get(sortField);

    // Handle null field values then actual value compares
    if(s1FieldValue == null && s2FieldValue == null) {
    compareResult = 0;
    } else if (s1FieldValue == null) {
    compareResult = -1;
    } else if (s2FieldValue == null) {
    compareResult = 1;
    } else {
    compareResult = compareFieldTypes(s1FieldValue, s2FieldValue);
    }
    }

    if(order == SortOrder.Descend) {
    return compareResult * -1;
    }
    return compareResult;
    }

    private integer compareFieldTypes(object s1FieldValue, object s2FieldValue) {
    switch on (describeResult.getType()) {
    when String {
    string s1 = (string)s1FieldValue;
    string s2 = (string)s2FieldValue;
    return (s1 < s2) ? -1 : (s1 > s2) ? 1 : 0;
    }
    when DateTime {
    DateTime s1 = (DateTime)s1FieldValue;
    DateTime s2 = (DateTime)s2FieldValue;
    return (s1 < s2) ? -1 : (s1 > s2) ? 1 : 0;
    }
    when Date {
    Date s1 = (Date)s1FieldValue;
    Date s2 = (Date)s2FieldValue;
    return (s1 < s2) ? -1 : (s1 > s2) ? 1 : 0;
    }
    when Integer {
    Integer s1 = (Integer)s1FieldValue;
    Integer s2 = (Integer)s2FieldValue;
    return (s1 < s2) ? -1 : (s1 > s2) ? 1 : 0;
    }
    when Id {
    Id s1 = (Id)s1FieldValue;
    Id s2 = (Id)s2FieldValue;
    return (s1 < s2) ? -1 : (s1 > s2) ? 1 : 0;
    }
    // TODO: Expand out for additional DisplayType enum values
    // https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_enum_Schema_DisplayType.htm
    when else {
    Assert.fail('Unable to compare field type: ' + describeResult.getType());
    }
    }
    return 0;
    }


    }
    72 changes: 72 additions & 0 deletions sObjectComparator_Test.cls
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    @IsTest
    public class sObjectComparator_Test {

    @IsTest
    static void AccountSorting() {
    List<Account> toSort = new List<Account>();
    toSort.add(new Account(Name='Test1', NumberOfEmployees=5));
    toSort.add(new Account(Name='Test3', NumberOfEmployees=2));
    toSort.add(new Account(Name='Test2'));
    toSort.add(null);

    sObjectComparator nameComp = new sObjectComparator(Account.Name);

    toSort.sort(nameComp);

    System.debug(toSort);
    Assert.isNull(toSort.get(0));
    Assert.areEqual('Test1', toSort.get(1).Name);
    Assert.areEqual('Test2', toSort.get(2).Name);
    Assert.areEqual('Test3', toSort.get(3).Name);

    sObjectComparator numEmpCom = new sObjectComparator(Account.NumberOfEmployees);

    toSort.sort(numEmpCom);
    Assert.isNull(toSort.get(0));
    Assert.areEqual('Test2', toSort.get(1).Name);
    Assert.areEqual('Test3', toSort.get(2).Name);
    Assert.areEqual('Test1', toSort.get(3).Name);

    numEmpCom.order = sObjectComparator.SortOrder.Descend;
    toSort.sort(numEmpCom);
    Assert.areEqual('Test1', toSort.get(0).Name);
    Assert.areEqual('Test3', toSort.get(1).Name);
    Assert.areEqual('Test2', toSort.get(2).Name);
    Assert.isNull(toSort.get(3));
    }

    @IsTest
    static void ContactSorting() {
    List<Contact> toSort = new List<Contact>();
    toSort.add(new Contact(LastName='Test1', Birthdate=DateTime.now().date()) );
    toSort.add(new Contact(LastName='Test3'));
    toSort.add(new Contact(LastName='Test2', Birthdate=DateTime.now().addDays(-10).date()));
    toSort.add(null);

    sObjectComparator nameComp = new sObjectComparator(Contact.LastName);

    toSort.sort(nameComp);

    System.debug(toSort);
    Assert.isNull(toSort.get(0));
    Assert.areEqual('Test1', toSort.get(1).LastName);
    Assert.areEqual('Test2', toSort.get(2).LastName);
    Assert.areEqual('Test3', toSort.get(3).LastName);

    sObjectComparator numEmpCom = new sObjectComparator(Contact.BirthDate);

    toSort.sort(numEmpCom);
    Assert.isNull(toSort.get(0));
    Assert.areEqual('Test3', toSort.get(1).LastName);
    Assert.areEqual('Test2', toSort.get(2).LastName);
    Assert.areEqual('Test1', toSort.get(3).LastName);

    numEmpCom.order = sObjectComparator.SortOrder.Descend;
    toSort.sort(numEmpCom);
    Assert.areEqual('Test1', toSort.get(0).LastName);
    Assert.areEqual('Test2', toSort.get(1).LastName);
    Assert.areEqual('Test3', toSort.get(2).LastName);
    Assert.isNull(toSort.get(3));
    }

    }